##// END OF EJS Templates
Fixes for py2.6
Jonathan Frederic -
Show More
@@ -1,155 +1,152 b''
1 # coding: utf-8
1 # coding: utf-8
2 """String filters.
2 """String filters.
3
3
4 Contains a collection of useful string manipulation filters for use in Jinja
4 Contains a collection of useful string manipulation filters for use in Jinja
5 templates.
5 templates.
6 """
6 """
7 #-----------------------------------------------------------------------------
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
8 # Copyright (c) 2013, the IPython Development Team.
9 #
9 #
10 # Distributed under the terms of the Modified BSD License.
10 # Distributed under the terms of the Modified BSD License.
11 #
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 # Imports
16 # Imports
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18
18
19 import re
19 import re
20 import textwrap
20 import textwrap
21 from xml.etree import ElementTree
21 from xml.etree import ElementTree
22 from types import StringTypes
22
23
23 from IPython.utils import py3compat
24 from IPython.utils import py3compat
24
25
25 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
26 # Functions
27 # Functions
27 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
28
29
29 __all__ = [
30 __all__ = [
30 'wrap',
31 'wrap',
31 'html_text',
32 'html_text',
32 'add_anchor',
33 'add_anchor',
33 'strip_dollars',
34 'strip_dollars',
34 'rm_fake',
35 'rm_fake',
35 'python_comment',
36 'python_comment',
36 'get_lines'
37 'get_lines'
37 ]
38 ]
38
39
39
40
40 def wrap(text, width=100):
41 def wrap(text, width=100):
41 """
42 """
42 Intelligently wrap text.
43 Intelligently wrap text.
43 Wrap text without breaking words if possible.
44 Wrap text without breaking words if possible.
44
45
45 Parameters
46 Parameters
46 ----------
47 ----------
47 text : str
48 text : str
48 Text to wrap.
49 Text to wrap.
49 width : int, optional
50 width : int, optional
50 Number of characters to wrap to, default 100.
51 Number of characters to wrap to, default 100.
51 """
52 """
52
53
53 split_text = text.split('\n')
54 split_text = text.split('\n')
54 wrp = map(lambda x:textwrap.wrap(x,width), split_text)
55 wrp = map(lambda x:textwrap.wrap(x,width), split_text)
55 wrpd = map('\n'.join, wrp)
56 wrpd = map('\n'.join, wrp)
56 return '\n'.join(wrpd)
57 return '\n'.join(wrpd)
57
58
58
59
59 def html_text(element):
60 def html_text(element):
60 """extract inner text from html
61 """extract inner text from html
61
62
62 Analog of jQuery's $(element).text()
63 Analog of jQuery's $(element).text()
63 """
64 """
64 instance_element_tree = isinstance(ElementTree.ElementTree, type) and \
65 if isinstance(element, StringTypes):
65 isinstance(element, (ElementTree.ElementTree))
66 instance_element = isinstance(ElementTree.Element, type) and \
67 isinstance(element, (ElementTree.Element))
68 if not (instance_element or instance_element_tree):
69 element = ElementTree.fromstring(element)
66 element = ElementTree.fromstring(element)
70
67
71 text = element.text or ""
68 text = element.text or ""
72 for child in element:
69 for child in element:
73 text += html_text(child)
70 text += html_text(child)
74 text += (element.tail or "")
71 text += (element.tail or "")
75 return text
72 return text
76
73
77
74
78 def add_anchor(html):
75 def add_anchor(html):
79 """Add an anchor-link to an html header tag
76 """Add an anchor-link to an html header tag
80
77
81 For use in heading cells
78 For use in heading cells
82 """
79 """
83 h = ElementTree.fromstring(py3compat.cast_bytes_py2(html))
80 h = ElementTree.fromstring(py3compat.cast_bytes_py2(html))
84 link = html_text(h).replace(' ', '-')
81 link = html_text(h).replace(' ', '-')
85 h.set('id', link)
82 h.set('id', link)
86 a = ElementTree.Element("a", {"class" : "anchor-link", "href" : "#" + link})
83 a = ElementTree.Element("a", {"class" : "anchor-link", "href" : "#" + link})
87 a.text = u'ΒΆ'
84 a.text = u'ΒΆ'
88 h.append(a)
85 h.append(a)
89 return ElementTree.tostring(h)
86 return ElementTree.tostring(h)
90
87
91
88
92 def strip_dollars(text):
89 def strip_dollars(text):
93 """
90 """
94 Remove all dollar symbols from text
91 Remove all dollar symbols from text
95
92
96 Parameters
93 Parameters
97 ----------
94 ----------
98 text : str
95 text : str
99 Text to remove dollars from
96 Text to remove dollars from
100 """
97 """
101
98
102 return text.strip('$')
99 return text.strip('$')
103
100
104
101
105 files_url_pattern = re.compile(r'(src|href)\=([\'"]?)files/')
102 files_url_pattern = re.compile(r'(src|href)\=([\'"]?)files/')
106
103
107 def rm_fake(text):
104 def rm_fake(text):
108 """
105 """
109 Fix all fake URLs that start with `files/`,
106 Fix all fake URLs that start with `files/`,
110 stripping out the `files/` prefix.
107 stripping out the `files/` prefix.
111
108
112 Parameters
109 Parameters
113 ----------
110 ----------
114 text : str
111 text : str
115 Text in which to replace 'src="files/real...' with 'src="real...'
112 Text in which to replace 'src="files/real...' with 'src="real...'
116 """
113 """
117 return files_url_pattern.sub(r"\1=\2", text)
114 return files_url_pattern.sub(r"\1=\2", text)
118
115
119
116
120 def python_comment(text):
117 def python_comment(text):
121 """
118 """
122 Build a Python comment line from input text.
119 Build a Python comment line from input text.
123
120
124 Parameters
121 Parameters
125 ----------
122 ----------
126 text : str
123 text : str
127 Text to comment out.
124 Text to comment out.
128 """
125 """
129
126
130 #Replace line breaks with line breaks and comment symbols.
127 #Replace line breaks with line breaks and comment symbols.
131 #Also add a comment symbol at the beginning to comment out
128 #Also add a comment symbol at the beginning to comment out
132 #the first line.
129 #the first line.
133 return '# '+'\n# '.join(text.split('\n'))
130 return '# '+'\n# '.join(text.split('\n'))
134
131
135
132
136 def get_lines(text, start=None,end=None):
133 def get_lines(text, start=None,end=None):
137 """
134 """
138 Split the input text into separate lines and then return the
135 Split the input text into separate lines and then return the
139 lines that the caller is interested in.
136 lines that the caller is interested in.
140
137
141 Parameters
138 Parameters
142 ----------
139 ----------
143 text : str
140 text : str
144 Text to parse lines from.
141 Text to parse lines from.
145 start : int, optional
142 start : int, optional
146 First line to grab from.
143 First line to grab from.
147 end : int, optional
144 end : int, optional
148 Last line to grab from.
145 Last line to grab from.
149 """
146 """
150
147
151 # Split the input into lines.
148 # Split the input into lines.
152 lines = text.split("\n")
149 lines = text.split("\n")
153
150
154 # Return the right lines.
151 # Return the right lines.
155 return "\n".join(lines[start:end]) #re-join
152 return "\n".join(lines[start:end]) #re-join
@@ -1,170 +1,171 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 """
2 """
3 Contains base test class for nbconvert
3 Contains base test class for nbconvert
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 #Copyright (c) 2013, the IPython Development Team.
6 #Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 #Distributed under the terms of the Modified BSD License.
8 #Distributed under the terms of the Modified BSD License.
9 #
9 #
10 #The full license is in the file COPYING.txt, distributed with this software.
10 #The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import subprocess
17 import subprocess
18 import os
18 import os
19 import glob
19 import glob
20 import shutil
20 import shutil
21 import sys
21
22
22 import IPython
23 import IPython
23 from IPython.utils.tempdir import TemporaryDirectory
24 from IPython.utils.tempdir import TemporaryDirectory
24
25
25 #-----------------------------------------------------------------------------
26 #-----------------------------------------------------------------------------
26 # Classes and functions
27 # Classes and functions
27 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
28
29
29 class TemporaryWorkingDirectory(TemporaryDirectory):
30 class TemporaryWorkingDirectory(TemporaryDirectory):
30 """
31 """
31 Creates a temporary directory and sets the cwd to that directory.
32 Creates a temporary directory and sets the cwd to that directory.
32 Automatically reverts to previous cwd upon cleanup.
33 Automatically reverts to previous cwd upon cleanup.
33 Usage example:
34 Usage example:
34
35
35 with TemporaryWorakingDirectory() as tmpdir:
36 with TemporaryWorakingDirectory() as tmpdir:
36 ...
37 ...
37 """
38 """
38
39
39 def __init__(self, **kw):
40 def __init__(self, **kw):
40 """
41 """
41 Constructor
42 Constructor
42 """
43 """
43 super(TemporaryWorkingDirectory, self).__init__(**kw)
44 super(TemporaryWorkingDirectory, self).__init__(**kw)
44
45
45 #Change cwd to new temp dir. Remember old cwd.
46 #Change cwd to new temp dir. Remember old cwd.
46 self.old_wd = os.getcwd()
47 self.old_wd = os.getcwd()
47 os.chdir(self.name)
48 os.chdir(self.name)
48
49
49
50
50 def cleanup(self):
51 def cleanup(self):
51 """
52 """
52 Destructor
53 Destructor
53 """
54 """
54
55
55 #Revert to old cwd.
56 #Revert to old cwd.
56 os.chdir(self.old_wd)
57 os.chdir(self.old_wd)
57
58
58 #Cleanup
59 #Cleanup
59 super(TemporaryWorkingDirectory, self).cleanup()
60 super(TemporaryWorkingDirectory, self).cleanup()
60
61
61
62
62 class TestsBase(object):
63 class TestsBase(object):
63 """Base tests class. Contains usefull fuzzy comparison and nbconvert
64 """Base tests class. Contains usefull fuzzy comparison and nbconvert
64 functions."""
65 functions."""
65
66
66
67
67 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
68 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
68 fuzzy_spacing=True, ignore_spaces=False,
69 fuzzy_spacing=True, ignore_spaces=False,
69 ignore_newlines=False, case_sensitive=False):
70 ignore_newlines=False, case_sensitive=False):
70 """
71 """
71 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
72 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
72 comparison that ignores insignificant differences in the two comparands.
73 comparison that ignores insignificant differences in the two comparands.
73 The significance of certain differences can be specified via the keyword
74 The significance of certain differences can be specified via the keyword
74 parameters of this method.
75 parameters of this method.
75 """
76 """
76
77
77 if newlines_are_spaces:
78 if newlines_are_spaces:
78 a = a.replace('\n', ' ')
79 a = a.replace('\n', ' ')
79 b = b.replace('\n', ' ')
80 b = b.replace('\n', ' ')
80
81
81 if tabs_are_spaces:
82 if tabs_are_spaces:
82 a = a.replace('\t', ' ')
83 a = a.replace('\t', ' ')
83 b = b.replace('\t', ' ')
84 b = b.replace('\t', ' ')
84
85
85 if ignore_spaces:
86 if ignore_spaces:
86 a = a.replace(' ', '')
87 a = a.replace(' ', '')
87 b = b.replace(' ', '')
88 b = b.replace(' ', '')
88
89
89 if fuzzy_spacing:
90 if fuzzy_spacing:
90 a = self.recursive_replace(a, ' ', ' ')
91 a = self.recursive_replace(a, ' ', ' ')
91 b = self.recursive_replace(b, ' ', ' ')
92 b = self.recursive_replace(b, ' ', ' ')
92
93
93 if ignore_newlines:
94 if ignore_newlines:
94 a = a.replace('\n', '')
95 a = a.replace('\n', '')
95 b = b.replace('\n', '')
96 b = b.replace('\n', '')
96
97
97 if not case_sensitive:
98 if not case_sensitive:
98 a = a.lower()
99 a = a.lower()
99 b = b.lower()
100 b = b.lower()
100
101
101 return a == b
102 return a == b
102
103
103
104
104 def recursive_replace(self, text, search, replacement):
105 def recursive_replace(self, text, search, replacement):
105 """
106 """
106 Performs a recursive replacement operation. Replaces all instances
107 Performs a recursive replacement operation. Replaces all instances
107 of a search string in a text string with a replacement string until
108 of a search string in a text string with a replacement string until
108 the search string no longer exists. Recursion is needed because the
109 the search string no longer exists. Recursion is needed because the
109 replacement string may generate additional search strings.
110 replacement string may generate additional search strings.
110
111
111 For example:
112 For example:
112 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
113 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
113 Another replacement yields "Hi" (the desired output)
114 Another replacement yields "Hi" (the desired output)
114
115
115 Parameters:
116 Parameters:
116 -----------
117 -----------
117 text : string
118 text : string
118 Text to replace in.
119 Text to replace in.
119 search : string
120 search : string
120 String to search for within "text"
121 String to search for within "text"
121 replacement : string
122 replacement : string
122 String to replace "search" with
123 String to replace "search" with
123 """
124 """
124 while search in text:
125 while search in text:
125 text = text.replace(search, replacement)
126 text = text.replace(search, replacement)
126 return text
127 return text
127
128
128
129
129 def create_temp_cwd(self, copy_filenames=None):
130 def create_temp_cwd(self, copy_filenames=None):
130 temp_dir = TemporaryWorkingDirectory()
131 temp_dir = TemporaryWorkingDirectory()
131
132
132 #Copy the files if requested.
133 #Copy the files if requested.
133 if not copy_filenames is None:
134 if not copy_filenames is None:
134 self.copy_files_to(copy_filenames)
135 self.copy_files_to(copy_filenames)
135
136
136 #Return directory handler
137 #Return directory handler
137 return temp_dir
138 return temp_dir
138
139
139
140
140 def copy_files_to(self, copy_filenames=None, destination=None):
141 def copy_files_to(self, copy_filenames=None, destination=None):
141
142
142 #Copy test files into the destination directory.
143 #Copy test files into the destination directory.
143 if copy_filenames:
144 if copy_filenames:
144 for pattern in copy_filenames:
145 for pattern in copy_filenames:
145 for match in glob.glob(os.path.join(self._get_files_path(), pattern)):
146 for match in glob.glob(os.path.join(self._get_files_path(), pattern)):
146 if destination is None:
147 if destination is None:
147 shutil.copyfile(match, os.path.basename(match))
148 shutil.copyfile(match, os.path.basename(match))
148 else:
149 else:
149 if not os.path.isdir(destination):
150 if not os.path.isdir(destination):
150 os.makedirs(destination)
151 os.makedirs(destination)
151 shutil.copyfile(match, os.path.join(destination, os.path.basename(match)))
152 shutil.copyfile(match, os.path.join(destination, os.path.basename(match)))
152
153
153
154
154 def _get_files_path(self):
155 def _get_files_path(self):
155
156
156 #Get the relative path to this module in the IPython directory.
157 #Get the relative path to this module in the IPython directory.
157 names = self.__module__.split('.')[1:-1]
158 names = self.__module__.split('.')[1:-1]
158 names.append('files')
159 names.append('files')
159
160
160 #Build a path using the IPython directory and the relative path we just
161 #Build a path using the IPython directory and the relative path we just
161 #found.
162 #found.
162 path = IPython.__path__[0]
163 path = IPython.__path__[0]
163 for name in names:
164 for name in names:
164 path = os.path.join(path, name)
165 path = os.path.join(path, name)
165 return path
166 return path
166
167
167
168
168 def call(self, parameters):
169 def call(self, parameters):
169 return subprocess.check_output(parameters)
170 return subprocess.Popen(parameters, stdout=subprocess.PIPE).communicate()[0]
170 No newline at end of file
171
General Comments 0
You need to be logged in to leave comments. Login now