# -*- coding: utf-8 -*- """ ============ brythonmagic ============ Magics for interacting with JS and the DOM via brython. .. note:: The ``brython`` javascript scripts need to be installed separately and can be obtained from https://github.com/brython-dev/brython You only need brython.js and brython_stdlib.js to be located in a place that could be easily loaded in the notebook Usage ===== To enable the magics below, execute ``%load_ext brythonmagic``. ``%%brython`` {BRYTHON_DOC} """ #----------------------------------------------------------------------------- # Copyright (C) 2014-2020 Kiko Correoso and the Brython team # # Distributed under the terms of the MIT License. The full license is in # the file LICENSE, distributed as part of this software. # # Contributors: # kikocorreoso # Polack Christian (baoboa) #----------------------------------------------------------------------------- import json from random import randint import warnings warnings.simplefilter("always") warnings.filterwarnings('default', category=DeprecationWarning, module='.*/brythonmagic/.*') #from urllib.request import urlopen from IPython.core.magic import Magics, magics_class,line_cell_magic from IPython.testing.skipdoctest import skip_doctest from IPython.core.magic_arguments import (argument, magic_arguments, parse_argstring) from IPython.utils.py3compat import unicode_to_str from IPython.utils.text import dedent from IPython.display import display, HTML, Javascript __version__ = "0.3.0dev" def load_js_lib(url): """Load a javascript file using requirejs. url : str string representing an url to a javascript file """ js_code = """ require( [ "%s" ], function() { console.log("Loaded js code from %s!"); } ); """ % (url, url) display(Javascript(js_code)) def load_brython_stable(version="3.6.2"): """Load the latest version of brython_dist.js (brython.js + available stdlib).""" load_js_lib( f"https://cdn.jsdelivr.net/npm/brython@{version}/brython.js" ) load_js_lib( f"https://cdn.jsdelivr.net/npm/brython@{version}/brython_stdlib.js" ) # def load_brython_dev(): # """Load the development version of brython_dist.js # (brython.js + available stdlib).""" # load_js_lib( # "https://raw.githack.com/brython-dev/brython/master/www/src/brython.js" # ) # load_js_lib( # "https://raw.githack.com/brython-dev/brython/master/www/src/brython_stdlib.js" # ) # def _create_gist_fiddle(input): # """Internal function to create a fiddle on jsfiddle.com from the code cell. # It uploads the code from the notebook code cell to an anonymous github gist # that will be used to create the final fiddle on jsfiddle. # """ # gdescr = """Gist created automatically using \ # https://github.com/kikocorreoso/brythonmagic by a \ # user of a Jupyter notebook""" # code = """
# {} # """.format(input) # mani = """name: Brythonmagic # description: Some description, please keep it in one line # authors: # - Automatically generated by Brythonmagic # resources: # - http://www.brython.info/src/brython_dist.js # normalize_css: no""" # data = {"description": gdescr, # "public": "true", # "files": {"fiddle.html": {"content": code}, # "fiddle.manifest": {"content": mani}}} # dataj = json.dumps(data) # req = urlopen('https://api.github.com/gists', # dataj.encode('utf8')) # data_req = json.loads(req.read().decode()) # jsf_url = 'http://jsfiddle.net/gh/gist/library/pure/{}/' # return data_req['html_url'], jsf_url.format(data_req['id']) class BrythonMagicError(Exception): pass @magics_class class BrythonMagics(Magics): """A set of magics useful for interactive work with the DOM API and javascript using Brython. """ def __init__(self, shell): super(BrythonMagics, self).__init__(shell) @skip_doctest @magic_arguments() @argument( '-i', '--input', action='append', nargs = "*", help = 'Names of input variables to be pushed to be available by the ' 'Brython script. Multiple variables are accepted and can be ' 'passed separated by whitespaces. Lists, Tuples, Dicts and ' 'Strings are converted to the same type in Brython.' ) @argument( '-c', '--container', action='append', nargs = "*", help = 'Name of html DIV container to be used to show the Brython ' 'output. Only one name is accepted.' ) @argument( '-h', '--html', action='append', nargs = "*", help = 'A string with some html code in order to avoid the creation ' 'of the html code from Brython code. Only one name is accepted.' ) @argument( '-s', '--script', action='append', nargs = "*", help = 'Name to be used for the id of the script tag where the ' 'brython code cell will be inserted. Only one name is accepted.' ) @argument( '-S', '--scripts', action='append', nargs = "*", help = 'id of the script tag of other Brython scripts not defined in ' 'the actual Brython code cell. Several ids separated by ' 'whitespaces are accepted.' ) @argument( '-p', '--print', action='store_true', help = 'If selected, the generated HTML code will be shown. ' 'Arguments are not accepted' ) # @argument( # '-f', '--fiddle', action='store_true', # help = 'If selected, the generated HTML will be uploaded anonymously ' # 'to gist.github.com and then create a jsfiddle example from ' # 'the gist. Arguments are not accepted' # ) # @argument( # '-e', '--embedfiddle', action='store_true', # help = 'If selected, the generated HTML will be uploaded anonymously ' # 'to gist.github.com and then create a jsfiddle example from ' # 'the gist and embed the final result in an iframe in the ' # 'notebook. Arguments are not accepted' # ) @argument( 'code', nargs='*', ) @line_cell_magic def brython(self, line, cell = None, local_ns = None): '''Execute code in Brython, and show the results in a DIV container if necessary:: As a cell, this will run a block of Brython code, returning results in a DIV if defined:: In [1]: %%brython -c 'output_123' ....: from browser import document, html ....: document['output_123'] <= html.P('Hello World!!') [You will seeHello World!!