示例#1
0
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)
示例#2
0
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
示例#3
0
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
示例#4
0
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
示例#5
0
文件: main.py 项目: GitAnt/Mathics
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
示例#6
0
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()})
示例#7
0
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
示例#8
0
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
示例#9
0
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
示例#10
0
文件: main.py 项目: nonohry/Mathics
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
示例#11
0
文件: kernel.py 项目: gjvnq/Mathics
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
示例#12
0
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
示例#13
0
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