# HG changeset patch
# User Andrey Novoseltsev <novoselt@gmail.com>
# Date 1264997067 25200
# Node ID fca3d8df3d5a420331fa85a40b821c9726b23337
# Parent 82ca63441af4b8bc701d1d44b1ca39bdce971494
Trac 7897: Improve prompt detection in Macaulay2 interface.
diff -r 82ca63441af4 -r fca3d8df3d5a sage/interfaces/macaulay2.py
a
|
b
|
|
105 | 105 | |
106 | 106 | def remove_output_labels(s): |
107 | 107 | """ |
| 108 | Remove output labels of Macaulay2 from a string. |
| 109 | |
| 110 | :param s: output of Macaulay2 |
| 111 | |
| 112 | :type s: string |
| 113 | |
| 114 | :returns: the input string with `n` symbols removed from the beginning |
| 115 | of each line, where `n` is the minimal number of spaces or |
| 116 | symbols of Macaulay2 output labels (looking like 'o39 = ') |
| 117 | present on every non-empty line. |
| 118 | |
| 119 | :rtype: string |
| 120 | |
| 121 | :note: If ``s`` consists of several outputs and their lables have |
| 122 | different width, it is possible that some strings will have leading |
| 123 | spaces (or maybe even pieces of output labels). However, this |
| 124 | function will try not cut any messages. |
| 125 | |
108 | 126 | EXAMPLES: |
109 | 127 | sage: from sage.interfaces.macaulay2 import remove_output_labels |
110 | 128 | sage: output = 'o1 = QQ [x, y]\n\no1 : PolynomialRing\n' |
111 | 129 | sage: remove_output_labels(output) |
112 | 130 | 'QQ [x, y]\n\nPolynomialRing\n' |
113 | 131 | """ |
114 | | m = re.search('o[0-9]+ = ', s) |
115 | | if m is None: return s |
116 | | i = m.start() |
117 | | j = m.end() |
118 | | n = j - i |
119 | | s = s[:i] + ' '*n + s[j:] |
120 | | # Now remove n spaces from beginning of each line. |
121 | | v = s.split('\n') |
122 | | s = '\n'.join([x[n:] for x in v]) |
123 | | return s |
124 | | |
| 132 | label = re.compile("^o[0-9]+ (=|:) |^ *") |
| 133 | lines = s.split("\n") |
| 134 | matches = [label.match(l) for l in lines if l != ""] |
| 135 | if len(matches) == 0: |
| 136 | return s |
| 137 | else: |
| 138 | n = min(m.end() - m.start() for m in matches) |
| 139 | return "\n".join(l[n:] for l in lines) |
125 | 140 | |
126 | 141 | COMMANDS_CACHE = '%s/macaulay2_commandlist_cache.sobj'%DOT_SAGE |
| 142 | PROMPT = "_EGAS_ : " |
127 | 143 | |
128 | 144 | class Macaulay2(Expect): |
129 | 145 | """ |
… |
… |
|
132 | 148 | def __init__(self, maxread=10000, script_subdirectory="", |
133 | 149 | logfile=None, server=None,server_tmpdir=None): |
134 | 150 | """ |
| 151 | Initialize a Macaulay2 interface instance. |
| 152 | |
| 153 | We replace the standard input prompt with a strange one, so that |
| 154 | we do not catch input prompts inside the documentation. |
| 155 | |
| 156 | We replace the standard input continuation prompt, which is |
| 157 | just a bunch of spaces and cannot be automatically detected in a |
| 158 | reliable way. This is necessary for allowing commands that occupy |
| 159 | several strings. |
| 160 | |
| 161 | We also change the starting line number to make all the output |
| 162 | labels to be of the same length. This allows correct stripping of |
| 163 | the output of several commands. |
| 164 | |
135 | 165 | TESTS: |
136 | 166 | sage: macaulay2 == loads(dumps(macaulay2)) |
137 | 167 | True |
138 | 168 | """ |
| 169 | init_str = ( |
| 170 | # Prompt changing commands |
| 171 | """ZZ#{Standard,Core#"private dictionary"#"InputPrompt"} = lineno -> "%s";""" % PROMPT + |
| 172 | """ZZ#{Standard,Core#"private dictionary"#"InputContinuationPrompt"} = lineno -> "%s";""" % PROMPT + |
| 173 | # Also prevent line wrapping in Macaulay2 |
| 174 | "printWidth = 0;" + |
| 175 | # And make all output labels to be of the same width |
| 176 | "lineNumber = 10^9;") |
139 | 177 | Expect.__init__(self, |
140 | 178 | name = 'macaulay2', |
141 | | prompt = 'i[0-9]* : ', |
142 | | command = "M2 --no-debug --no-readline --silent ", |
| 179 | prompt = PROMPT, |
| 180 | command = "M2 --no-debug --no-readline --silent -e '%s'" % init_str, |
143 | 181 | maxread = maxread, |
144 | 182 | server = server, |
145 | 183 | server_tmpdir = server_tmpdir, |
… |
… |
|
227 | 265 | ans = remove_output_labels(ans) |
228 | 266 | return AsciiArtString(ans) |
229 | 267 | |
| 268 | def restart(self): |
| 269 | r""" |
| 270 | Restart Macaulay2 interpreter. |
| 271 | |
| 272 | TEST: |
| 273 | sage: macaulay2.restart() # optional |
| 274 | """ |
| 275 | # If we allow restart to be called as a function, there will be |
| 276 | # parasitic output |
| 277 | self.eval("restart") |
| 278 | |
230 | 279 | def get(self, var): |
231 | 280 | """ |
232 | 281 | Get the value of the variable var. |