def set_settings_value(definitions: Definitions, setting_name: str, value): """Set a Mathics Settings` with name "setting_name" from definitions to value "value". """ return definitions.set_ownvalue(setting_name, value)
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument('--execute', '-e', nargs='?', help='execute a command') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--version', '-v', action='version', version=get_version_string(False)) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(1)) #Reset the line number to 1 shell = TerminalShell(definitions, args.colors) if not (args.quiet or args.script): print_version(is_server=False) print_license() print u"Quit by pressing {0}\n".format(quit_command) if args.execute: total_input = args.execute.decode(sys.stdin.encoding) # check encoding print shell.get_in_prompt() + total_input shell.evaluate(total_input) return if args.FILE is not None: total_input = '' for line_no, line in enumerate(args.FILE): try: line = line.decode('utf-8') # TODO: other encodings if args.script and line_no == 0 and line.startswith('#!'): continue print shell.get_in_prompt( continued=(total_input != '')) + line, total_input += ' ' + line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break if not args.persist: return total_input = "" while True: try: line = raw_input(shell.get_in_prompt(continued=total_input != '')) line = line.decode(sys.stdin.encoding) total_input += line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument( 'FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument( '--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument( '--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument( '-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument( '--colors', nargs='?', help='interactive shell colors') argparser.add_argument( '--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument( '--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number shell = TerminalShell( definitions, args.colors, want_readline=not(args.no_readline), want_completion=not(args.no_completion)) if not (args.quiet or args.script): print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) exprs = evaluation.parse(expr) results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT) shell.print_results(results) if not args.persist: return if args.FILE is not None: lines = args.FILE.readlines() if args.script and lines[0].startswith('#!'): lines[0] = '' results = [] query_gen = parse_lines(lines, shell.definitions) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) try: for query in query_gen: results.extend(evaluation.evaluate([query], timeout=settings.TIMEOUT)) except TranslateError as exc: evaluation.recursion_depth = 0 evaluation.stopped = False evaluation.message('Syntax', exc.msg, *exc.args) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") if not args.persist: return total_input = "" while True: try: evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) line = shell.read_line(shell.get_in_prompt(continued=total_input != '')) total_input += line try: query = parse(total_input, shell.definitions) except TranslateError as exc: if line == '' or not isinstance(exc, IncompleteSyntaxError): evaluation.message('Syntax', exc.msg, *exc.args) total_input = "" continue total_input = "" if query is None: continue results = evaluation.evaluate([query], timeout=settings.TIMEOUT) shell.print_results(results) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument( 'FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument( '--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument( '--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument( '-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument( '--colors', nargs='?', help='interactive shell colors') argparser.add_argument( '--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument( '--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number shell = TerminalShell( definitions, args.colors, want_readline=not(args.no_readline), want_completion=not(args.no_completion)) if not (args.quiet or args.script): print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) if args.execute: for expr in args.execute: # expr = expr.decode(shell.input_encoding) print(shell.get_in_prompt() + expr) shell.evaluate(expr) if not args.persist: return if args.FILE is not None: total_input = '' for line_no, line in enumerate(args.FILE): try: # line = line.decode('utf-8') # TODO: other encodings if args.script and line_no == 0 and line.startswith('#!'): continue print(shell.get_in_prompt(continued=total_input != '') + line.rstrip('\n')) total_input += ' ' + line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break if not args.persist: return total_input = "" while True: try: line = shell.read_line( shell.get_in_prompt(continued=total_input != '')) total_input += line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument( 'FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument( '--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE', action='store_true') argparser.add_argument( '--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument( '-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', nargs='?', help='execute a command') argparser.add_argument( '--colors', nargs='?', help='interactive shell colors') argparser.add_argument( '--version', '-v', action='version', version=get_version_string(False)) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number shell = TerminalShell(definitions, args.colors) if not (args.quiet or args.script): print_version(is_server=False) print_license() print u"Quit by pressing {0}\n".format(quit_command) if args.execute: total_input = args.execute.decode(shell.input_encoding) print shell.get_in_prompt() + total_input shell.evaluate(total_input) return if args.FILE is not None: total_input = '' for line_no, line in enumerate(args.FILE): try: line = line.decode('utf-8') # TODO: other encodings if args.script and line_no == 0 and line.startswith('#!'): continue print shell.get_in_prompt(continued=total_input != '') + line, total_input += ' ' + line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break if not args.persist: return total_input = "" while True: try: line = shell.read_line( shell.get_in_prompt(continued=total_input != '')) line = line.decode(shell.input_encoding) total_input += line if line != "" and wait_for_line(total_input): continue shell.evaluate(total_input) total_input = "" except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break
class MathicsKernel(Kernel): import re svg_open_tag = re.compile('<mtable><mtr><mtd><svg') svg_close_tag = re.compile('</svg></mtd></mtr></mtable>') implementation = 'Mathics' implementation_version = __version__ language_version = '0.1' # TODO language_info = { 'name': 'Mathematica', 'mimetype': 'text/x-mathematica', } banner = "Mathics kernel" # TODO def __init__(self, **kwargs): self.mathjax_initialized = False Kernel.__init__(self, **kwargs) if self.log is None: # This occurs if we call as a stand-alone kernel # (eg, not as a process) # FIXME: take care of input/output, eg StringIO # make work without a session self.log = logging.Logger("NotebookApp") self.definitions = Definitions(add_builtin=True) # TODO Cache self.definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): #Initialize mathjax... It should be a beter place to do it inside the imathics kernel if not self.mathjax_initialized: self.mathjax_initialized = True self.Display(Javascript(''' MathJax.Hub.Config({jax: ["input/TeX","input/MathML","input/AsciiMath","output/HTML-CSS","output/NativeMML", "output/PreviewHTML"],extensions: ["tex2jax.js","mml2jax.js","asciimath2jax.js","MathMenu.js","MathZoom.js", "fast-preview.js", "AssistiveMML.js"],TeX: { extensions: ["AMSmath.js","AMSsymbols.js","noErrors.js", "noUndefined.js"]}});''', lib="https://cdn.mathjax.org/mathjax/latest/MathJax.js")) # TODO update user definitions response = { 'payload': [], 'user_expressions': {}, } try: evaluation = Evaluation(code, self.definitions, out_callback=self.out_callback, timeout=settings.TIMEOUT,format="xml") except Exception as exc: response['status'] = 'error' response['ename'] = 'System:exception' response['traceback'] = traceback.format_exception(*sys.exc_info()) evaluation = Evaluation() raise exc else: response['status'] = 'ok' if not silent: for result in evaluation.results: if result.result is not None: xmlchain = result.result xmlchain= MathicsKernel.svg_open_tag.sub("<mtable><mtr><mtd><annotation-xml encoding=\"text/html\" ><svg",xmlchain) xmlchain= MathicsKernel.svg_close_tag.sub("</svg></annotation-xml></mtd></mtr></mtable>",xmlchain) data = { 'text/html': xmlchain, # TODO html / mathjax output } content = {'execution_count': result.line_no, 'data': data, 'metadata': {}} self.send_response(self.iopub_socket, 'execute_result', content) response['execution_count'] = self.definitions.get_line() return response def out_callback(self, out): if out.is_message: content = { 'name': 'stderr', 'text': '{symbol}::{tag}: {text}\n'.format(**out.get_data()), } elif out.is_print: content = { 'name': 'stdout', 'text': out.text + '\n', } else: raise ValueError('Unknown out') self.send_response(self.iopub_socket, 'stream', content) def do_inspect(self, code, cursor_pos, detail_level=0): # name = code[:cursor_pos] name = code if '`' not in name: name = 'System`' + name try: instance = builtins[name] except KeyError: return {'status': 'ok', 'found': False, 'data': {}, 'metadata': {}} doc = Doc(instance.__doc__ or '') # TODO Handle possible ValueError here data = {'text/plain': doc.text(detail_level), 'text/html': doc.html()} # TODO 'application/x-tex': doc.latex() return {'status': 'ok', 'found': True, 'data': data, 'metadata': {}} @staticmethod def do_is_complete(code): code = code.rstrip() trailing_ops = ['+', '-', '/', '*', '^', '=', '>', '<', '/;', '/:', '/.', '&&', '||'] if any(code.endswith(op) for op in trailing_ops): return {'status': 'incomplete', 'indent': ''} brackets = [('(', ')'), ('[', ']'), ('{', '}')] kStart, kEnd, stack = 0, 1, [] in_string = False for char in code: if char == '"': in_string = not in_string if not in_string: for bracketPair in brackets: if char == bracketPair[kStart]: stack.append(char) elif char == bracketPair[kEnd]: if len(stack) == 0: return {'status': 'invalid'} if stack.pop() != bracketPair[kStart]: return {'status': 'invalid'} if in_string: return {'status': 'incomplete', 'indent': ''} elif len(stack) != 0: return {'status': 'incomplete', 'indent': 4 * len(stack) * ' '} else: return {'status': 'complete'} #Borrowed from metakernel package def repr(self, item): return repr(item) #Borrowed from metakernel package def Display(self, *args, **kwargs): clear_output = kwargs.get("clear_output", False) for message in args: if isinstance(message, HTML): if clear_output: self.send_response(self.iopub_socket, 'clear_output', {'wait': True}) # if Widget and isinstance(message, Widget): # self.log.debug('Display Widget') # self._ipy_formatter(message) else: self.log.debug('Display Data') try: data = _formatter(message, self.repr) except Exception as e: self.Error(e) return self.send_response(self.iopub_socket, 'display_data', {'data': data, 'metadata': dict()})
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description = "Mathics is a general-purpose computer algebra system.", epilog = """Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument('--persist', help='go to interactive shell after evaluating FILE', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument('--execute', '-e', nargs='?', help='execute a command') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--version', '-v', action='version', version=get_version_string(False)) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) # TODO all binary operators? #Reset the line number to 1 definitions.set_ownvalue('$Line', Integer(1)) shell = TerminalShell(definitions, args.colors) if args.execute: total_input = args.execute.decode(sys.stdin.encoding) # check encoding print shell.get_in_prompt() + total_input evaluation = Evaluation(total_input, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output(unicode(result.result)) + '\n' return if not (args.quiet or args.script): print_version(is_server=False) print_license() print u"Quit by pressing %s" % quit_command print '' if args.FILE is not None: total_input = "" for line in args.FILE: line = line.decode('utf-8') # TODO: other encodings if args.script and line.startswith('#!'): continue if total_input == "": print shell.get_in_prompt() + line, else: print ' ', line, total_input += line if line == "": pass elif wait_for_line(total_input): continue evaluation = Evaluation(total_input, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output(unicode(result.result)) + '\n' total_input = "" if not args.persist: return while True: try: total_input = "" line_input = raw_input(shell.get_in_prompt()) line_input = line_input.decode(sys.stdin.encoding) while line_input != "": total_input += ' ' + line_input if not wait_for_line(total_input): break line_input = raw_input(' ') line_input = line_input.decode(sys.stdin.encoding) evaluation = Evaluation(total_input, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output(unicode(result.result)) + '\n' except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break
class MathicsKernel(Kernel): implementation = 'Mathics' implementation_version = '0.1' language_info = { 'version': __version__, 'name': 'Mathematica', 'mimetype': 'text/x-mathematica', } banner = "Mathics kernel" # TODO def __init__(self, **kwargs): Kernel.__init__(self, **kwargs) self.definitions = Definitions(add_builtin=True) # TODO Cache self.definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number self.establish_comm_manager() # needed for ipywidgets and Manipulate[] def establish_comm_manager(self): self.comm_manager = CommManager(parent=self, kernel=self) comm_msg_types = ['comm_open', 'comm_msg', 'comm_close'] for msg_type in comm_msg_types: self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): # TODO update user definitions response = { 'payload': [], 'user_expressions': {}, } evaluation = Evaluation(self.definitions, result_callback=self.result_callback, out_callback=self.out_callback, clear_output_callback=self.clear_output_callback, display_data_callback=self.display_data_callback) try: results = evaluation.parse_evaluate(code, timeout=settings.TIMEOUT) except Exception as exc: # internal error response['status'] = 'error' response['ename'] = 'System:exception' response['traceback'] = traceback.format_exception(*sys.exc_info()) results = [] else: response['status'] = 'ok' response['execution_count'] = self.definitions.get_line_no() return response def out_callback(self, out): if out.is_message: content = { 'name': 'stderr', 'text': '{symbol}::{tag}: {text}\n'.format(**out.get_data()), } elif out.is_print: content = { 'name': 'stdout', 'text': out.text + '\n', } else: raise ValueError('Unknown out') self.send_response(self.iopub_socket, 'stream', content) def result_callback(self, result): content = { 'execution_count': result.line_no, 'data': result.data, 'metadata': result.metadata, } self.send_response(self.iopub_socket, 'execute_result', content) def clear_output_callback(self, wait=False): # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = dict(wait=wait) self.send_response(self.iopub_socket, 'clear_output', content) def display_data_callback(self, result): # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = { 'data': result.data, 'metadata': result.metadata, } self.send_response(self.iopub_socket, 'display_data', content) def do_inspect(self, code, cursor_pos, detail_level=0): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} if '`' not in name: name = 'System`' + name try: instance = builtins[name] except KeyError: return {'status': 'ok', 'found': False, 'data': {}, 'metadata': {}} doc = Doc(instance.__doc__ or '') data = { 'text/plain': str(doc), # TODO latex # TODO html } return {'status': 'ok', 'found': True, 'data': data, 'metadata': {}} def do_complete(self, code, cursor_pos): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} remove_system = False system_prefix = 'System`' if '`' not in name: name = system_prefix + name remove_system = True matches = [] for key in builtins: if key.startswith(name): matches.append(key) if remove_system: matches = [match[len(system_prefix):] for match in matches] return { 'status': 'ok', 'matches': matches, 'cursor_start': start_pos, 'cursor_end': end_pos, 'metadata': {}, } def do_is_complete(self, code): try: # list forces generator evaluation (parse all lines) list(parse_lines(code, self.definitions)) except IncompleteSyntaxError: return {'status': 'incomplete', 'indent': ''} except TranslateError: return {'status': 'invalid'} else: return {'status': 'complete'} @staticmethod def find_symbol_name(code, cursor_pos): ''' Given a string of code tokenize it until cursor_pos and return the final symbol name. returns None if no symbol is found at cursor_pos. >>> MathicsKernel.find_symbol_name('1 + Sin', 6) 'System`Sin' >>> MathicsKernel.find_symbol_name('1 + ` Sin[Cos[2]] + x', 8) 'System`Sin' >>> MathicsKernel.find_symbol_name('Sin `', 4) ''' scanner = MathicsScanner() scanner.build() scanner.lexer.input(code) start_pos = None end_pos = None name = None while True: try: token = scanner.lexer.token() except ScanError: scanner.lexer.skip(1) continue if token is None: break # ran out of tokens # find first token which contains cursor_pos if scanner.lexer.lexpos >= cursor_pos: if token.type == 'symbol': name = token.value start_pos = token.lexpos end_pos = scanner.lexer.lexpos break return start_pos, end_pos, name
class MathicsKernel(Kernel): implementation = 'Mathics' implementation_version = '0.1' language_info = { 'version': __version__, 'name': 'Mathematica', 'mimetype': 'text/x-mathematica', } banner = "Mathics kernel" # TODO shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True) shell_class = Type(ZMQInteractiveShell) user_module = Any() user_ns = Instance(dict, args=None, allow_none=True) def __init__(self, **kwargs): Kernel.__init__(self, **kwargs) self.definitions = Definitions(add_builtin=True) # TODO Cache self.definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number self.establish_comm_manager() # needed for ipywidgets and Manipulate[] self.web_engine = None def establish_comm_manager(self): # see ipykernel/ipkernel.py self.shell = self.shell_class.instance( parent=self, profile_dir=self.profile_dir, user_module=self.user_module, user_ns=self.user_ns, kernel=self) self.shell.displayhook.session = self.session self.shell.displayhook.pub_socket = self.iopub_socket self.shell.displayhook.topic = self._topic('execute_result') self.shell.display_pub.session = self.session self.shell.display_pub.pub_socket = self.iopub_socket self.comm_manager = CommManager(parent=self, kernel=self) comm_msg_types = ['comm_open', 'comm_msg', 'comm_close'] for msg_type in comm_msg_types: self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) def init_web_engine(self): if self.web_engine is None: self.web_engine = WebEngine() def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): # TODO update user definitions response = { 'payload': [], 'user_expressions': {}, } formats = { 'text/plain': 'text', 'text/html': 'xml', 'text/latex': 'tex', } try: self.init_web_engine() evaluation = Evaluation(self.definitions, output=KernelOutput(self), format=formats) result = evaluation.parse_evaluate(code, timeout=settings.TIMEOUT) if result: self.result_callback(result) except Exception as exc: stack = traceback.format_exception(*sys.exc_info()) self.out_callback(Print('An error occured: ' + str(exc) + '\n\n' + '\n'.join(stack))) # internal error response['status'] = 'error' response['ename'] = 'System:exception' response['traceback'] = stack else: response['status'] = 'ok' response['execution_count'] = self.definitions.get_line_no() return response def out_callback(self, out): if out.is_message: content = { 'name': 'stderr', 'text': '{symbol}::{tag}: {text}\n'.format(**out.get_data()), } elif out.is_print: content = { 'name': 'stdout', 'text': out.text + '\n', } else: raise ValueError('Unknown out') self.send_response(self.iopub_socket, 'stream', content) def reconfigure_mathjax(self): # Jupyter's default MathJax configuration ("safe" mode) blocks the use # of data uris which we use in mglyphs for displaying svgs and imgs. # enable the "data" protocol here. also remove font size restrictions. # we set processSectionDelay to 0 since that drastically improves the # visual experience of Manipulate as there's a lot less jitter, also see # http://docs.mathjax.org/en/latest/api/hub.html safeModeJS = """ MathJax.Hub.Config({ showMathMenu: false, showProcessingMessages: false, messageStyle: "normal", displayAlign: "left", Safe: { safeProtocols: { data: true }, allow: { fontsize: "all" } }, "HTML-CSS": { availableFonts: [], /* force Web font */ preferredFont: null, /* force Web font */ webFont: "Asana-Math", linebreaks: { automatic: true, width: "70%" } } }); MathJax.Hub.processSectionDelay = 0; """ # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = { 'data': {'application/javascript': safeModeJS}, 'metadata': {}, } self.send_response(self.iopub_socket, 'display_data', content) def result_callback(self, result): self.reconfigure_mathjax() content = { 'execution_count': result.line_no, 'data': result.result, 'metadata': {}, } self.send_response(self.iopub_socket, 'execute_result', content) def clear_output_callback(self, wait=False): # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = dict(wait=wait) self.send_response(self.iopub_socket, 'clear_output', content) def display_data_callback(self, data, metadata): self.reconfigure_mathjax() # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = { 'data': data, 'metadata': metadata, } self.send_response(self.iopub_socket, 'display_data', content) def do_inspect(self, code, cursor_pos, detail_level=0): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} if '`' not in name: name = 'System`' + name try: instance = builtins[name] except KeyError: return {'status': 'ok', 'found': False, 'data': {}, 'metadata': {}} doc = Doc(instance.__doc__ or '') data = { 'text/plain': str(doc), # TODO latex # TODO html } return {'status': 'ok', 'found': True, 'data': data, 'metadata': {}} def do_complete(self, code, cursor_pos): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} remove_system = False system_prefix = 'System`' if '`' not in name: name = system_prefix + name remove_system = True matches = [] for key in builtins: if key.startswith(name): matches.append(key) if remove_system: matches = [match[len(system_prefix):] for match in matches] return { 'status': 'ok', 'matches': matches, 'cursor_start': start_pos, 'cursor_end': end_pos, 'metadata': {}, } def do_is_complete(self, code): try: # list forces generator evaluation (parse all lines) list(parse_lines(code, self.definitions)) except IncompleteSyntaxError: return {'status': 'incomplete', 'indent': ''} except TranslateError: return {'status': 'invalid'} else: return {'status': 'complete'} @staticmethod def find_symbol_name(code, cursor_pos): ''' Given a string of code tokenize it until cursor_pos and return the final symbol name. returns None if no symbol is found at cursor_pos. >>> MathicsKernel.find_symbol_name('1 + Sin', 6) 'System`Sin' >>> MathicsKernel.find_symbol_name('1 + ` Sin[Cos[2]] + x', 8) 'System`Sin' >>> MathicsKernel.find_symbol_name('Sin `', 4) ''' tokeniser = Tokeniser(SingleLineFeeder(code)) start_pos = None end_pos = None name = None while True: try: token = tokeniser.next() except ScanError: continue if token.tag == 'END': break # ran out of tokens # find first token which contains cursor_pos if tokeniser.pos >= cursor_pos: if token.tag == 'Symbol': name = token.text start_pos = token.pos end_pos = tokeniser.pos break return start_pos, end_pos, name
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument('--execute', '-e', nargs='?', help='execute a command') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--version', '-v', action='version', version=get_version_string(False)) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) # TODO all binary operators? #Reset the line number to 1 definitions.set_ownvalue('$Line', Integer(1)) shell = TerminalShell(definitions, args.colors) if args.execute: print get_in_prompt() + args.execute evaluation = Evaluation(args.execute, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output(unicode( result.result)) + '\n' return if not (args.quiet or args.script): print_version(is_server=False) print_license() print u"Quit by pressing %s" % quit_command print '' if args.FILE is not None: total_input = "" for line in args.FILE: if args.script and line.startswith('#!'): continue if total_input == "": print shell.get_in_prompt() + line, else: print ' ', line, total_input += line if line == "": pass elif wait_for_line(total_input): continue evaluation = Evaluation(total_input, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output( unicode(result.result)) + '\n' total_input = "" if not args.persist: return while True: try: total_input = "" line_input = raw_input(shell.get_in_prompt()) while line_input != "": total_input += ' ' + line_input if not wait_for_line(total_input): break line_input = raw_input(' ') evaluation = Evaluation(total_input, definitions, timeout=30, out_callback=out_callback) for result in evaluation.results: if result.result is not None: print shell.get_out_prompt() + to_output( unicode(result.result)) + '\n' except (KeyboardInterrupt): print '\nKeyboardInterrupt' except (SystemExit, EOFError): print "\n\nGood bye!\n" break
class MathicsKernel(Kernel): implementation = 'Mathics' implementation_version = '0.1' language_info = { 'version': __version__, 'name': 'Mathematica', 'mimetype': 'text/x-mathematica', } banner = "Mathics kernel" # TODO shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True) shell_class = Type(ZMQInteractiveShell) user_module = Any() user_ns = Instance(dict, args=None, allow_none=True) def __init__(self, **kwargs): Kernel.__init__(self, **kwargs) self.definitions = Definitions(add_builtin=True) # TODO Cache self.definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number self.establish_comm_manager() # needed for ipywidgets and Manipulate[] self.web_engine = None def establish_comm_manager(self): # see ipykernel/ipkernel.py self.shell = self.shell_class.instance(parent=self, profile_dir=self.profile_dir, user_module=self.user_module, user_ns=self.user_ns, kernel=self) self.shell.displayhook.session = self.session self.shell.displayhook.pub_socket = self.iopub_socket self.shell.displayhook.topic = self._topic('execute_result') self.shell.display_pub.session = self.session self.shell.display_pub.pub_socket = self.iopub_socket self.comm_manager = CommManager(parent=self, kernel=self) comm_msg_types = ['comm_open', 'comm_msg', 'comm_close'] for msg_type in comm_msg_types: self.shell_handlers[msg_type] = getattr(self.comm_manager, msg_type) def init_web_engine(self): if self.web_engine is None: self.web_engine = WebEngine() def do_execute(self, code, silent, store_history=True, user_expressions=None, allow_stdin=False): # TODO update user definitions response = { 'payload': [], 'user_expressions': {}, } formats = { 'text/plain': 'text', 'text/html': 'xml', 'text/latex': 'tex', } try: self.init_web_engine() evaluation = Evaluation(self.definitions, output=KernelOutput(self), format=formats) result = evaluation.parse_evaluate(code, timeout=settings.TIMEOUT) if result: self.result_callback(result) except Exception as exc: stack = traceback.format_exception(*sys.exc_info()) self.out_callback( Print('An error occured: ' + str(exc) + '\n\n' + '\n'.join(stack))) # internal error response['status'] = 'error' response['ename'] = 'System:exception' response['traceback'] = stack else: response['status'] = 'ok' response['execution_count'] = self.definitions.get_line_no() return response def out_callback(self, out): if out.is_message: content = { 'name': 'stderr', 'text': '{symbol}::{tag}: {text}\n'.format(**out.get_data()), } elif out.is_print: content = { 'name': 'stdout', 'text': out.text + '\n', } else: raise ValueError('Unknown out') self.send_response(self.iopub_socket, 'stream', content) def reconfigure_mathjax(self): # Jupyter's default MathJax configuration ("safe" mode) blocks the use # of data uris which we use in mglyphs for displaying svgs and imgs. # enable the "data" protocol here. also remove font size restrictions. # we set processSectionDelay to 0 since that drastically improves the # visual experience of Manipulate as there's a lot less jitter, also see # http://docs.mathjax.org/en/latest/api/hub.html safeModeJS = """ MathJax.Hub.Config({ showMathMenu: false, showProcessingMessages: false, messageStyle: "normal", displayAlign: "left", Safe: { safeProtocols: { data: true }, allow: { fontsize: "all" } }, "HTML-CSS": { availableFonts: [], /* force Web font */ preferredFont: null, /* force Web font */ webFont: "Asana-Math", linebreaks: { automatic: true, width: "70%" } } }); MathJax.Hub.processSectionDelay = 0; """ # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = { 'data': { 'application/javascript': safeModeJS }, 'metadata': {}, } self.send_response(self.iopub_socket, 'display_data', content) def result_callback(self, result): self.reconfigure_mathjax() content = { 'execution_count': result.line_no, 'data': result.result, 'metadata': {}, } self.send_response(self.iopub_socket, 'execute_result', content) def clear_output_callback(self, wait=False): # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = dict(wait=wait) self.send_response(self.iopub_socket, 'clear_output', content) def display_data_callback(self, data, metadata): self.reconfigure_mathjax() # see http://jupyter-client.readthedocs.org/en/latest/messaging.html content = { 'data': data, 'metadata': metadata, } self.send_response(self.iopub_socket, 'display_data', content) def do_inspect(self, code, cursor_pos, detail_level=0): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} if '`' not in name: name = 'System`' + name try: instance = builtins[name] except KeyError: return {'status': 'ok', 'found': False, 'data': {}, 'metadata': {}} doc = Doc(instance.__doc__ or '') data = { 'text/plain': str(doc), # TODO latex # TODO html } return {'status': 'ok', 'found': True, 'data': data, 'metadata': {}} def do_complete(self, code, cursor_pos): start_pos, end_pos, name = self.find_symbol_name(code, cursor_pos) if name is None: return {'status': 'error'} remove_system = False system_prefix = 'System`' if '`' not in name: name = system_prefix + name remove_system = True matches = [] for key in builtins: if key.startswith(name): matches.append(key) if remove_system: matches = [match[len(system_prefix):] for match in matches] return { 'status': 'ok', 'matches': matches, 'cursor_start': start_pos, 'cursor_end': end_pos, 'metadata': {}, } def do_is_complete(self, code): try: # list forces generator evaluation (parse all lines) list(parse_lines(code, self.definitions)) except IncompleteSyntaxError: return {'status': 'incomplete', 'indent': ''} except TranslateError: return {'status': 'invalid'} else: return {'status': 'complete'} @staticmethod def find_symbol_name(code, cursor_pos): ''' Given a string of code tokenize it until cursor_pos and return the final symbol name. returns None if no symbol is found at cursor_pos. >>> MathicsKernel.find_symbol_name('1 + Sin', 6) 'System`Sin' >>> MathicsKernel.find_symbol_name('1 + ` Sin[Cos[2]] + x', 8) 'System`Sin' >>> MathicsKernel.find_symbol_name('Sin `', 4) ''' tokeniser = Tokeniser(SingleLineFeeder(code)) start_pos = None end_pos = None name = None while True: try: token = tokeniser.next() except ScanError: continue if token.tag == 'END': break # ran out of tokens # find first token which contains cursor_pos if tokeniser.pos >= cursor_pos: if token.tag == 'Symbol': name = token.text start_pos = token.pos end_pos = tokeniser.pos break return start_pos, end_pos, name
def main(): argparser = argparse.ArgumentParser( prog='mathics', usage='%(prog)s [options] [FILE]', add_help=False, description="Mathics is a general-purpose computer algebra system.", epilog="""Please feel encouraged to contribute to Mathics! Create your own fork, make the desired changes, commit, and make a pull request.""") argparser.add_argument('FILE', nargs='?', type=argparse.FileType('r'), help='execute commands from FILE') argparser.add_argument('--help', '-h', help='show this help message and exit', action='help') argparser.add_argument( '--persist', help='go to interactive shell after evaluating FILE or -e', action='store_true') argparser.add_argument('--quiet', '-q', help='don\'t print message at startup', action='store_true') argparser.add_argument('-script', help='run a mathics file in script mode', action='store_true') argparser.add_argument( '--execute', '-e', action='append', metavar='EXPR', help='evaluate EXPR before processing any input files (may be given ' 'multiple times)') argparser.add_argument('--colors', nargs='?', help='interactive shell colors') argparser.add_argument('--no-completion', help="disable tab completion", action='store_true') argparser.add_argument( '--no-readline', help="disable line editing (implies --no-completion)", action='store_true') argparser.add_argument('--version', '-v', action='version', version='%(prog)s ' + __version__) args = argparser.parse_args() quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-D' definitions = Definitions(add_builtin=True) definitions.set_ownvalue('$Line', Integer(0)) # Reset the line number shell = TerminalShell(definitions, args.colors, want_readline=not (args.no_readline), want_completion=not (args.no_completion)) if not (args.quiet or args.script): print() print(version_string + '\n') print(license_string + '\n') print("Quit by pressing {0}\n".format(quit_command)) if args.execute: for expr in args.execute: print(shell.get_in_prompt() + expr) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) exprs = evaluation.parse(expr) results = evaluation.evaluate(exprs, timeout=settings.TIMEOUT) shell.print_results(results) if not args.persist: return if args.FILE is not None: lines = args.FILE.readlines() if args.script and lines[0].startswith('#!'): lines[0] = '' results = [] query_gen = parse_lines(lines, shell.definitions) evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) try: for query in query_gen: results.extend( evaluation.evaluate([query], timeout=settings.TIMEOUT)) except TranslateError as exc: evaluation.recursion_depth = 0 evaluation.stopped = False evaluation.message('Syntax', exc.msg, *exc.args) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") if not args.persist: return total_input = "" while True: try: evaluation = Evaluation(shell.definitions, out_callback=shell.out_callback) line = shell.read_line( shell.get_in_prompt(continued=total_input != '')) total_input += line try: query = parse(total_input, shell.definitions) except TranslateError as exc: if line == '' or not isinstance(exc, IncompleteSyntaxError): evaluation.message('Syntax', exc.msg, *exc.args) total_input = "" continue total_input = "" if query is None: continue results = evaluation.evaluate([query], timeout=settings.TIMEOUT) shell.print_results(results) except (KeyboardInterrupt): print('\nKeyboardInterrupt') except (SystemExit, EOFError): print("\n\nGood bye!\n") break
def main( full_form, persist, quiet, readline, completion, unicode, prompt, pyextensions, execute, run, style, pygments_tokens, strict_wl_output, file, ) -> int: """A command-line interface to Mathics. Mathics is a general-purpose computer algebra system """ exit_rc = 0 quit_command = "CTRL-BREAK" if sys.platform == "win32" else "CONTROL-D" extension_modules = [] if pyextensions: for ext in pyextensions: extension_modules.append(ext) definitions = Definitions(add_builtin=True) definitions.set_line_no(0) # Set a default value for $ShowFullFormInput to False. # Then, it can be changed by the settings file (in WL) # and overwritten by the command line parameter. definitions.set_ownvalue( "Settings`$ShowFullFormInput", from_python(True if full_form else False) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(True if pygments_tokens else False) ) readline = "none" if (execute or file and not persist) else readline.lower() if readline == "prompt": shell = TerminalShellPromptToolKit( definitions, style, completion, unicode, prompt ) else: want_readline = readline == "gnu" shell = TerminalShellGNUReadline( definitions, style, want_readline, completion, unicode, prompt ) load_settings(shell) if run: with open(run, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") definitions.set_line_no(0) if execute: for expr in execute: evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), format="text" ) shell.terminal_formatter = None result = evaluation.parse_evaluate(expr, timeout=settings.TIMEOUT) shell.print_result(result, prompt, "text", strict_wl_output) # After the next release, we can remove the hasattr test. if hasattr(evaluation, "exc_result"): if evaluation.exc_result == Symbol("Null"): exit_rc = 0 elif evaluation.exc_result == Symbol("$Aborted"): exit_rc = -1 elif evaluation.exc_result == Symbol("Overflow"): exit_rc = -2 else: exit_rc = -3 if not persist: return exit_rc if file is not None: with open(file, "r") as ifile: feeder = MathicsFileLineFeeder(ifile) try: while not feeder.empty(): evaluation = Evaluation( shell.definitions, output=TerminalOutput(shell), catch_interrupt=False, format="text", ) query = evaluation.parse_feeder(feeder) if query is None: continue evaluation.evaluate(query, timeout=settings.TIMEOUT) except (KeyboardInterrupt): print("\nKeyboardInterrupt") if not persist: return exit_rc if not quiet and prompt: print(f"\nMathicscript: {__version__}, {version_string}\n") print(license_string + "\n") print(f"Quit by evaluating Quit[] or by pressing {quit_command}.\n") # If defined, full_form and style overwrite the predefined values. definitions.set_ownvalue( "Settings`$ShowFullFormInput", SymbolTrue if full_form else SymbolFalse ) definitions.set_ownvalue( "Settings`$PygmentsStyle", from_python(shell.pygments_style) ) definitions.set_ownvalue( "Settings`$PygmentsShowTokens", from_python(pygments_tokens) ) definitions.set_ownvalue("Settings`MathicsScriptVersion", from_python(__version__)) definitions.set_attribute("Settings`MathicsScriptVersion", "System`Protected") definitions.set_attribute("Settings`MathicsScriptVersion", "System`Locked") TeXForm = Symbol("System`TeXForm") definitions.set_line_no(0) while True: try: if have_readline and shell.using_readline: import readline as GNU_readline last_pos = GNU_readline.get_current_history_length() full_form = definitions.get_ownvalue( "Settings`$ShowFullFormInput" ).replace.to_python() style = definitions.get_ownvalue("Settings`$PygmentsStyle") fmt = lambda x: x if style: style = style.replace.get_string_value() if shell.terminal_formatter: fmt = lambda x: highlight( str(query), mma_lexer, shell.terminal_formatter ) evaluation = Evaluation(shell.definitions, output=TerminalOutput(shell)) query, source_code = evaluation.parse_feeder_returning_code(shell) if ( have_readline and shell.using_readline and hasattr(GNU_readline, "remove_history_item") ): current_pos = GNU_readline.get_current_history_length() for pos in range(last_pos, current_pos - 1): GNU_readline.remove_history_item(pos) wl_input = source_code.rstrip() if unicode: wl_input = replace_wl_with_plain_text(wl_input) GNU_readline.add_history(wl_input) if query is None: continue if hasattr(query, "head") and query.head == TeXForm: output_style = "//TeXForm" else: output_style = "" if full_form: print(fmt(query)) result = evaluation.evaluate( query, timeout=settings.TIMEOUT, format="unformatted" ) if result is not None: shell.print_result( result, prompt, output_style, strict_wl_output=strict_wl_output ) except ShellEscapeException as e: source_code = e.line if len(source_code) and source_code[1] == "!": try: print(open(source_code[2:], "r").read()) except: print(str(sys.exc_info()[1])) else: subprocess.run(source_code[1:], shell=True) # Should we test exit code for adding to history? GNU_readline.add_history(source_code.rstrip()) # FIXME add this... when in Mathics core updated # shell.defintions.increment_line(1) except (KeyboardInterrupt): print("\nKeyboardInterrupt") except EOFError: if prompt: print("\n\nGoodbye!\n") break except SystemExit: print("\n\nGoodbye!\n") # raise to pass the error code on, e.g. Quit[1] raise finally: # Reset the input line that would be shown in a parse error. # This is not to be confused with the number of complete # inputs that have been seen, i.e. In[] shell.reset_lineno() return exit_rc