diff --git a/IPython/html/static/notebook/js/menubar.js b/IPython/html/static/notebook/js/menubar.js index af04c8f..ee01a41 100644 --- a/IPython/html/static/notebook/js/menubar.js +++ b/IPython/html/static/notebook/js/menubar.js @@ -76,7 +76,7 @@ define([ notebook_path ) + "?download=" + download.toString(); - var w = window.open() + var w = window.open(); if (this.notebook.dirty) { this.notebook.save_notebook().then(function() { w.location = url; @@ -332,6 +332,7 @@ define([ this.events.on('kernel_ready.Kernel', function(event, data) { var langinfo = data.kernel.info_reply.language_info || {}; that.update_nbconvert_script(langinfo); + that.add_kernel_help_links(data.kernel.info_reply.help_links || []); }); }; @@ -374,11 +375,49 @@ define([ var that = this; // Set menu entry text to e.g. "Python (.py)" - var langname = (langinfo.name || 'Script') - langname = langname.charAt(0).toUpperCase()+langname.substr(1) // Capitalise + var langname = (langinfo.name || 'Script'); + langname = langname.charAt(0).toUpperCase()+langname.substr(1); // Capitalise el.find('a').text(langname + ' ('+(langinfo.file_extension || 'txt')+')'); }; + MenuBar.prototype.add_kernel_help_links = function(help_links) { + /** add links from kernel_info to the help menu */ + var divider = $("#kernel-help-links"); + if (divider.length === 0) { + // insert kernel help section above about link + var about = $("#notebook_about").parent(); + divider = $("
  • ") + .attr('id', "kernel-help-links") + .addClass('divider'); + about.prev().before(divider); + } + // remove previous entries + while (!divider.next().hasClass('divider')) { + divider.next().remove(); + } + if (help_links.length === 0) { + // no help links, remove the divider + divider.remove(); + return; + } + var cursor = divider; + help_links.map(function (link) { + cursor.after($("
  • ") + .append($("") + .attr('target', '_blank') + .attr('title', 'Opens in a new window') + .attr('href', link.url) + .text(link.text) + .append($("") + .addClass("fa fa-external-link menu-icon pull-right") + ) + ) + ); + cursor = cursor.next(); + }); + + }; + // Backwards compatability. IPython.MenuBar = MenuBar; diff --git a/IPython/html/templates/notebook.html b/IPython/html/templates/notebook.html index cfc6de9..dbefa0a 100644 --- a/IPython/html/templates/notebook.html +++ b/IPython/html/templates/notebook.html @@ -246,17 +246,9 @@ class="notebook_app" {% set sections = ( ( - ("http://ipython.org/documentation.html","IPython Help",True), - ("http://nbviewer.ipython.org/github/ipython/ipython/tree/2.x/examples/Index.ipynb", "Notebook Help", True), - ),( - ("http://docs.python.org","Python",True), + ("http://nbviewer.ipython.org/github/ipython/ipython/blob/2.x/examples/Index.ipynb", "Notebook Help", True), ("http://help.github.com/articles/github-flavored-markdown","Markdown",True), - ("http://docs.scipy.org/doc/numpy/reference/","NumPy",True), - ("http://docs.scipy.org/doc/scipy/reference/","SciPy",True), - ("http://matplotlib.org/contents.html","Matplotlib",True), - ("http://docs.sympy.org/latest/index.html","SymPy",True), - ("http://pandas.pydata.org/pandas-docs/stable/","pandas", True) - ) + ), ) %} diff --git a/IPython/kernel/zmq/ipkernel.py b/IPython/kernel/zmq/ipkernel.py index 0143d12..b06a268 100644 --- a/IPython/kernel/zmq/ipkernel.py +++ b/IPython/kernel/zmq/ipkernel.py @@ -7,7 +7,7 @@ import traceback from IPython.core import release from IPython.utils.py3compat import builtin_mod, PY3 from IPython.utils.tokenutil import token_at_cursor, line_at_cursor -from IPython.utils.traitlets import Instance, Type, Any +from IPython.utils.traitlets import Instance, Type, Any, List from IPython.utils.decorators import undoc from ..comm import CommManager @@ -70,6 +70,37 @@ class IPythonKernel(KernelBase): 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) + + help_links = List([ + { + 'text': "Python", + 'url': "http://docs.python.org/%i.%i" % sys.version_info[:2], + }, + { + 'text': "IPython", + 'url': "http://ipython.org/documentation.html", + }, + { + 'text': "NumPy", + 'url': "http://docs.scipy.org/doc/numpy/reference/", + }, + { + 'text': "SciPy", + 'url': "http://docs.scipy.org/doc/scipy/reference/", + }, + { + 'text': "Matplotlib", + 'url': "http://matplotlib.org/contents.html", + }, + { + 'text': "SymPy", + 'url': "http://docs.sympy.org/latest/index.html", + }, + { + 'text': "pandas", + 'url': "http://pandas.pydata.org/pandas-docs/stable/", + }, + ]) # Kernel info fields implementation = 'ipython' diff --git a/IPython/kernel/zmq/kernelbase.py b/IPython/kernel/zmq/kernelbase.py index 7b59656..396d1d5 100755 --- a/IPython/kernel/zmq/kernelbase.py +++ b/IPython/kernel/zmq/kernelbase.py @@ -63,6 +63,9 @@ class Kernel(SingletonConfigurable): # This should be overridden by wrapper kernels that implement any real # language. language_info = {} + + # any links that should go in the help menu + help_links = List() # Private interface @@ -457,6 +460,7 @@ class Kernel(SingletonConfigurable): 'implementation_version': self.implementation_version, 'language_info': self.language_info, 'banner': self.banner, + 'help_links': self.help_links, } def kernel_info_request(self, stream, ident, parent):