~soren/nova/iptables-security-groups

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/python/text.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.test.test_text -*-
 
2
#
 
3
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
4
# See LICENSE for details.
 
5
 
 
6
 
 
7
"""Miscellany of text-munging functions.
 
8
"""
 
9
 
 
10
import string, types
 
11
 
 
12
def stringyString(object, indentation=''):
 
13
    """Expansive string formatting for sequence types.
 
14
 
 
15
    list.__str__ and dict.__str__ use repr() to display their
 
16
    elements.  This function also turns these sequence types
 
17
    into strings, but uses str() on their elements instead.
 
18
 
 
19
    Sequence elements are also displayed on seperate lines,
 
20
    and nested sequences have nested indentation.
 
21
    """
 
22
    braces = ''
 
23
    sl = []
 
24
 
 
25
    if type(object) is types.DictType:
 
26
        braces = '{}'
 
27
        for key, value in object.items():
 
28
            value = stringyString(value, indentation + '   ')
 
29
            if isMultiline(value):
 
30
                if endsInNewline(value):
 
31
                    value = value[:-len('\n')]
 
32
                sl.append("%s %s:\n%s" % (indentation, key, value))
 
33
            else:
 
34
                # Oops.  Will have to move that indentation.
 
35
                sl.append("%s %s: %s" % (indentation, key,
 
36
                                         value[len(indentation) + 3:]))
 
37
 
 
38
    elif type(object) in (types.TupleType, types.ListType):
 
39
        if type(object) is types.TupleType:
 
40
            braces = '()'
 
41
        else:
 
42
            braces = '[]'
 
43
 
 
44
        for element in object:
 
45
            element = stringyString(element, indentation + ' ')
 
46
            sl.append(string.rstrip(element) + ',')
 
47
    else:
 
48
        sl[:] = map(lambda s, i=indentation: i+s,
 
49
                    string.split(str(object),'\n'))
 
50
 
 
51
    if not sl:
 
52
        sl.append(indentation)
 
53
 
 
54
    if braces:
 
55
        sl[0] = indentation + braces[0] + sl[0][len(indentation) + 1:]
 
56
        sl[-1] = sl[-1] + braces[-1]
 
57
 
 
58
    s = string.join(sl, "\n")
 
59
 
 
60
    if isMultiline(s) and not endsInNewline(s):
 
61
        s = s + '\n'
 
62
 
 
63
    return s
 
64
 
 
65
def isMultiline(s):
 
66
    """Returns True if this string has a newline in it."""
 
67
    return (string.find(s, '\n') != -1)
 
68
 
 
69
def endsInNewline(s):
 
70
    """Returns True if this string ends in a newline."""
 
71
    return (s[-len('\n'):] == '\n')
 
72
 
 
73
def docstringLStrip(docstring):
 
74
    """Gets rid of unsightly lefthand docstring whitespace residue.
 
75
 
 
76
    You'd think someone would have done this already, but apparently
 
77
    not in 1.5.2.
 
78
 
 
79
    BUT since we're all using Python 2.1 now, use L{inspect.getdoc}
 
80
    instead.  I{This function should go away soon.}
 
81
    """
 
82
 
 
83
    if not docstring:
 
84
        return docstring
 
85
 
 
86
    docstring = string.replace(docstring, '\t', ' ' * 8)
 
87
    lines = string.split(docstring,'\n')
 
88
 
 
89
    leading = 0
 
90
    for l in xrange(1,len(lines)):
 
91
        line = lines[l]
 
92
        if string.strip(line):
 
93
            while 1:
 
94
                if line[leading] == ' ':
 
95
                    leading = leading + 1
 
96
                else:
 
97
                    break
 
98
        if leading:
 
99
            break
 
100
 
 
101
    outlines = lines[0:1]
 
102
    for l in xrange(1,len(lines)):
 
103
        outlines.append(lines[l][leading:])
 
104
 
 
105
    return string.join(outlines, '\n')
 
106
 
 
107
def greedyWrap(inString, width=80):
 
108
    """Given a string and a column width, return a list of lines.
 
109
 
 
110
    Caveat: I'm use a stupid greedy word-wrapping
 
111
    algorythm.  I won't put two spaces at the end
 
112
    of a sentence.  I don't do full justification.
 
113
    And no, I've never even *heard* of hypenation.
 
114
    """
 
115
 
 
116
    outLines = []
 
117
 
 
118
    #eww, evil hacks to allow paragraphs delimited by two \ns :(
 
119
    if inString.find('\n\n') >= 0:
 
120
        paragraphs = string.split(inString, '\n\n')
 
121
        for para in paragraphs:
 
122
            outLines.extend(greedyWrap(para) + [''])
 
123
        return outLines
 
124
    inWords = string.split(inString)
 
125
 
 
126
    column = 0
 
127
    ptr_line = 0
 
128
    while inWords:
 
129
        column = column + len(inWords[ptr_line])
 
130
        ptr_line = ptr_line + 1
 
131
 
 
132
        if (column > width):
 
133
            if ptr_line == 1:
 
134
                # This single word is too long, it will be the whole line.
 
135
                pass
 
136
            else:
 
137
                # We've gone too far, stop the line one word back.
 
138
                ptr_line = ptr_line - 1
 
139
            (l, inWords) = (inWords[0:ptr_line], inWords[ptr_line:])
 
140
            outLines.append(string.join(l,' '))
 
141
 
 
142
            ptr_line = 0
 
143
            column = 0
 
144
        elif not (len(inWords) > ptr_line):
 
145
            # Clean up the last bit.
 
146
            outLines.append(string.join(inWords, ' '))
 
147
            del inWords[:]
 
148
        else:
 
149
            # Space
 
150
            column = column + 1
 
151
    # next word
 
152
 
 
153
    return outLines
 
154
 
 
155
 
 
156
wordWrap = greedyWrap
 
157
 
 
158
def removeLeadingBlanks(lines):
 
159
    ret = []
 
160
    for line in lines:
 
161
        if ret or line.strip():
 
162
            ret.append(line)
 
163
    return ret
 
164
 
 
165
def removeLeadingTrailingBlanks(s):
 
166
    lines = removeLeadingBlanks(s.split('\n'))
 
167
    lines.reverse()
 
168
    lines = removeLeadingBlanks(lines)
 
169
    lines.reverse()
 
170
    return '\n'.join(lines)+'\n'
 
171
 
 
172
def splitQuoted(s):
 
173
    """Like string.split, but don't break substrings inside quotes.
 
174
 
 
175
    >>> splitQuoted('the \"hairy monkey\" likes pie')
 
176
    ['the', 'hairy monkey', 'likes', 'pie']
 
177
 
 
178
    Another one of those \"someone must have a better solution for
 
179
    this\" things.  This implementation is a VERY DUMB hack done too
 
180
    quickly.
 
181
    """
 
182
    out = []
 
183
    quot = None
 
184
    phrase = None
 
185
    for word in s.split():
 
186
        if phrase is None:
 
187
            if word and (word[0] in ("\"", "'")):
 
188
                quot = word[0]
 
189
                word = word[1:]
 
190
                phrase = []
 
191
 
 
192
        if phrase is None:
 
193
            out.append(word)
 
194
        else:
 
195
            if word and (word[-1] == quot):
 
196
                word = word[:-1]
 
197
                phrase.append(word)
 
198
                out.append(" ".join(phrase))
 
199
                phrase = None
 
200
            else:
 
201
                phrase.append(word)
 
202
 
 
203
    return out
 
204
 
 
205
def strFile(p, f, caseSensitive=True):
 
206
    """Find whether string p occurs in a read()able object f
 
207
    @rtype: C{bool}
 
208
    """
 
209
    buf = ""
 
210
    buf_len = max(len(p), 2**2**2**2)
 
211
    if not caseSensitive:
 
212
        p = p.lower()
 
213
    while 1:
 
214
        r = f.read(buf_len-len(p))
 
215
        if not caseSensitive:
 
216
            r = r.lower()
 
217
        bytes_read = len(r)
 
218
        if bytes_read == 0:
 
219
            return False
 
220
        l = len(buf)+bytes_read-buf_len
 
221
        if l <= 0:
 
222
            buf = buf + r
 
223
        else:
 
224
            buf = buf[l:] + r
 
225
        if buf.find(p) != -1:
 
226
            return True
 
227