##// END OF EJS Templates
Factor out handling of line continuations
Thomas Kluyver -
Show More
@@ -93,12 +93,33 b' def _find_assign_op(token_line):'
93 93 elif s in ')]}':
94 94 paren_level -= 1
95 95
96 def find_end_of_continued_line(lines, start_line: int):
97 """Find the last line of a line explicitly extended using backslashes.
98
99 Uses 0-indexed line numbers.
100 """
101 end_line = start_line
102 while lines[end_line].endswith('\\\n'):
103 end_line += 1
104 if end_line >= len(lines):
105 break
106 return end_line
107
108 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
109 """Assemble pieces of a continued line into a single line.
110
111 Uses 0-indexed line numbers. *start* is (lineno, colno).
112 """
113 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
114 return ' '.join([p[:-2] for p in parts[:-1]] # Strip backslash+newline
115 + [parts[-1][:-1]]) # Strip newline from last line
116
96 117 class MagicAssign:
97 118 @staticmethod
98 119 def find(tokens_by_line):
99 120 """Find the first magic assignment (a = %foo) in the cell.
100 121
101 Returns (line, column) of the % if found, or None.
122 Returns (line, column) of the % if found, or None. *line* is 1-indexed.
102 123 """
103 124 for line in tokens_by_line:
104 125 assign_ix = _find_assign_op(line)
@@ -115,20 +136,11 b' class MagicAssign:'
115 136 start_line = start[0] - 1 # Shift from 1-index to 0-index
116 137 start_col = start[1]
117 138
118 print("Start at", start_line, start_col)
119 print("Line", lines[start_line])
120
121 lhs, rhs = lines[start_line][:start_col], lines[start_line][start_col:-1]
139 lhs = lines[start_line][:start_col]
140 end_line = find_end_of_continued_line(lines, start_line)
141 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
122 142 assert rhs.startswith('%'), rhs
123 143 magic_name, _, args = rhs[1:].partition(' ')
124 args_parts = [args]
125 end_line = start_line
126 # Follow explicit (backslash) line continuations
127 while end_line < len(lines) and args_parts[-1].endswith('\\'):
128 end_line += 1
129 args_parts[-1] = args_parts[-1][:-1] # Trim backslash
130 args_parts.append(lines[end_line][:-1]) # Trim newline
131 args = ' '.join(args_parts)
132 144
133 145 lines_before = lines[:start_line]
134 146 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
@@ -143,7 +155,7 b' class SystemAssign:'
143 155 def find(tokens_by_line):
144 156 """Find the first system assignment (a = !foo) in the cell.
145 157
146 Returns (line, column) of the ! if found, or None.
158 Returns (line, column) of the ! if found, or None. *line* is 1-indexed.
147 159 """
148 160 for line in tokens_by_line:
149 161 assign_ix = _find_assign_op(line)
@@ -166,20 +178,11 b' class SystemAssign:'
166 178 start_line = start[0] - 1 # Shift from 1-index to 0-index
167 179 start_col = start[1]
168 180
169 print("Start at", start_line, start_col)
170 print("Line", lines[start_line])
171
172 lhs, rhs = lines[start_line][:start_col], lines[start_line][
173 start_col:-1]
181 lhs = lines[start_line][:start_col]
182 end_line = find_end_of_continued_line(lines, start_line)
183 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
174 184 assert rhs.startswith('!'), rhs
175 cmd_parts = [rhs[1:]]
176 end_line = start_line
177 # Follow explicit (backslash) line continuations
178 while end_line < len(lines) and cmd_parts[-1].endswith('\\'):
179 end_line += 1
180 cmd_parts[-1] = cmd_parts[-1][:-1] # Trim backslash
181 cmd_parts.append(lines[end_line][:-1]) # Trim newline
182 cmd = ' '.join(cmd_parts)
185 cmd = rhs[1:]
183 186
184 187 lines_before = lines[:start_line]
185 188 call = "get_ipython().getoutput({!r})".format(cmd)
@@ -25,6 +25,12 b" b = get_ipython().getoutput('foo bar')"
25 25 g()
26 26 """.splitlines(keepends=True))
27 27
28 def test_continued_line():
29 lines = MULTILINE_MAGIC_ASSIGN[0]
30 nt.assert_equal(ipt2.find_end_of_continued_line(lines, 1), 2)
31
32 nt.assert_equal(ipt2.assemble_continued_line(lines, (1, 5), 2), "foo bar")
33
28 34 def test_find_assign_magic():
29 35 tbl = make_tokens_by_line(MULTILINE_MAGIC_ASSIGN[0])
30 36 nt.assert_equal(ipt2.MagicAssign.find(tbl), (2, 4))
General Comments 0
You need to be logged in to leave comments. Login now