@@ -101,6 +101,7 @@ def regex_from_encoded_pattern(s):
101
101
else : # not an encoded regex
102
102
return re .compile (re .escape (s ))
103
103
104
+
104
105
# Recipe: dedent (0.1.2)
105
106
def dedentlines (lines , tabsize = 8 , skip_first_line = False ):
106
107
"""dedentlines(lines, tabsize=8, skip_first_line=False) -> dedented lines
@@ -116,55 +117,64 @@ def dedentlines(lines, tabsize=8, skip_first_line=False):
116
117
"""
117
118
DEBUG = False
118
119
if DEBUG :
119
- print ("dedent: dedent(..., tabsize=%d, skip_first_line=%r)" \
120
- % (tabsize , skip_first_line ))
120
+ print (
121
+ "dedent: dedent(..., tabsize=%d, skip_first_line=%r)"
122
+ % (tabsize , skip_first_line )
123
+ )
121
124
margin = None
122
125
for i , line in enumerate (lines ):
123
- if i == 0 and skip_first_line : continue
126
+ if i == 0 and skip_first_line :
127
+ continue
124
128
indent = 0
125
129
for ch in line :
126
- if ch == ' ' :
130
+ if ch == " " :
127
131
indent += 1
128
- elif ch == ' \t ' :
132
+ elif ch == " \t " :
129
133
indent += tabsize - (indent % tabsize )
130
- elif ch in ' \r \n ' :
134
+ elif ch in " \r \n " :
131
135
continue # skip all-whitespace lines
132
136
else :
133
137
break
134
138
else :
135
139
continue # skip all-whitespace lines
136
- if DEBUG : print ("dedent: indent=%d: %r" % (indent , line ))
140
+ if DEBUG :
141
+ print ("dedent: indent=%d: %r" % (indent , line ))
137
142
if margin is None :
138
143
margin = indent
139
144
else :
140
145
margin = min (margin , indent )
141
- if DEBUG : print ("dedent: margin=%r" % margin )
146
+ if DEBUG :
147
+ print ("dedent: margin=%r" % margin )
142
148
143
149
if margin is not None and margin > 0 :
144
150
for i , line in enumerate (lines ):
145
- if i == 0 and skip_first_line : continue
151
+ if i == 0 and skip_first_line :
152
+ continue
146
153
removed = 0
147
154
for j , ch in enumerate (line ):
148
- if ch == ' ' :
155
+ if ch == " " :
149
156
removed += 1
150
- elif ch == ' \t ' :
157
+ elif ch == " \t " :
151
158
removed += tabsize - (removed % tabsize )
152
- elif ch in '\r \n ' :
153
- if DEBUG : print ("dedent: %r: EOL -> strip up to EOL" % line )
159
+ elif ch in "\r \n " :
160
+ if DEBUG :
161
+ print ("dedent: %r: EOL -> strip up to EOL" % line )
154
162
lines [i ] = lines [i ][j :]
155
163
break
156
164
else :
157
- raise ValueError ("unexpected non-whitespace char %r in "
158
- "line %r while removing %d-space margin"
159
- % (ch , line , margin ))
165
+ raise ValueError (
166
+ "unexpected non-whitespace char %r in "
167
+ "line %r while removing %d-space margin" % (ch , line , margin )
168
+ )
160
169
if DEBUG :
161
- print ("dedent: %r: %r -> removed %d/%d" \
162
- % (line , ch , removed , margin ))
170
+ print (
171
+ "dedent: %r: %r -> removed %d/%d" % (line , ch , removed , margin )
172
+ )
163
173
if removed == margin :
164
- lines [i ] = lines [i ][j + 1 :]
174
+ lines [i ] = lines [i ][j + 1 :]
165
175
break
166
176
elif removed > margin :
167
- lines [i ] = ' ' * (removed - margin ) + lines [i ][j + 1 :]
177
+ lines [i ] = " " * (removed - margin ) + lines [i ][j + 1 :]
168
178
break
169
179
else :
170
180
if removed :
@@ -185,7 +195,7 @@ def dedent(text, tabsize=8, skip_first_line=False):
185
195
"""
186
196
lines = text .splitlines (1 )
187
197
dedentlines (lines , tabsize = tabsize , skip_first_line = skip_first_line )
188
- return '' .join (lines )
198
+ return "" .join (lines )
189
199
190
200
191
201
class memoized (object ):
@@ -195,6 +205,7 @@ class memoized(object):
195
205
196
206
http://wiki.python.org/moin/PythonDecoratorLibrary
197
207
"""
208
+
198
209
def __init__ (self , func ):
199
210
self .func = func
200
211
self .cache = {}
@@ -215,10 +226,10 @@ def __repr__(self):
215
226
return self .func .__doc__
216
227
217
228
218
-
219
229
def xml_oneliner_re_from_tab_width (tab_width ):
220
230
"""Standalone XML processing instruction regex."""
221
- return re .compile (r"""
231
+ return re .compile (
232
+ r"""
222
233
(?:
223
234
(?<=\n\n) # Starting after a blank line
224
235
| # or
@@ -234,5 +245,36 @@ def xml_oneliner_re_from_tab_width(tab_width):
234
245
[ \t]*
235
246
(?=\n{2,}|\Z) # followed by a blank line or end of document
236
247
)
237
- """ % (tab_width - 1 ), re .X )
248
+ """
249
+ % (tab_width - 1 ),
250
+ re .X ,
251
+ )
252
+
253
+
238
254
xml_oneliner_re_from_tab_width = memoized (xml_oneliner_re_from_tab_width )
255
+
256
+
257
+ def hr_tag_re_from_tab_width (tab_width ):
258
+ return re .compile (
259
+ r"""
260
+ (?:
261
+ (?<=\n\n) # Starting after a blank line
262
+ | # or
263
+ \A\n? # the beginning of the doc
264
+ )
265
+ ( # save in \1
266
+ [ ]{0,%d}
267
+ <(hr) # start tag = \2
268
+ \b # word break
269
+ ([^<>])*? #
270
+ /?> # the matching end tag
271
+ [ \t]*
272
+ (?=\n{2,}|\Z) # followed by a blank line or end of document
273
+ )
274
+ """
275
+ % (tab_width - 1 ),
276
+ re .X ,
277
+ )
278
+
279
+
280
+ hr_tag_re_from_tab_width = memoized (hr_tag_re_from_tab_width )
0 commit comments