# JPSLMenus
[Introduction](#introduction) |
[Create Menu with a module](#create-a-menu-on-import-of-a-python-module) |
[Create Menu within a Notebook](#create-a-menu-from-within-a-notebook) |
[Installation](#installation) | [Change Log](#change-log) |
[License](#this-software-is-distributed-under-the-gnu-v3-licensehttpsgnuorglicenses)
## Introduction
This package contains utilities for building hierarchical menus that appear in
the Jupyter notebook menu bar. Unlike extensions, these menus can be added
using python import statements, so only appear in notebooks where the
module(s) that creates them are imported.
The expectation is that *JPSLMenus* will be imported into the notebook by
other modules when they are imported so that each module can use these
javascript menu creation tools to construct their own menus. It is also
possible to create a menu on-the-fly from javascript in a code cell
([see below](#create-a-menu-from-within-a-notebook)).
## Create a menu on import of a python module
(NOTE: below may need modifying to work with a slow connection. Maybe use
`promise` to wait until the object `JPSLMenus` is defined?)
1. Create a javascript file containing a menu creation function that defines
all menu elements, the menu structure and calls `JPSLMenus.build(menu)`:
* Menu elements are defined by the following template:
```
var item = {'type':'url|action|snippet|computedsnippet|submenu|menu',
'title':'String that will appear in menu',
'data': \\depends on type
\\ url: "string url"
\\ action: "single line of valid javascript"
\\ snippet: ["code line 1","code line 2"...]
\\ computedsnippet: "single line of valid javascript"
\\ that returns a string representation of the
\\ snippet to insert.
\\ submenu: [item1, item2...] items can be submenus.
\\ menu: [item1, item2...] items can be submenus.
};
```
* Only one item of type menu should be passed to the build function. It
will pull in each item as defined in the data array for the menu.
* To minimize possible namespace collisions it is suggested that you
build your menu creation function as in the following example.
```
let NameOfYourModule = new Object();
NameOfYourModule.createMenu = function(){
var aurl={'type':'url',
'title':'Lewis Structure Tutorial',
'data':'https://cms.gutow.uwosh.edu/Gutow/tutorials/lewis-structure-tutorial'
};
var anaction ={'type':'action',
'title':'Flag selected cells in pink',
'data':"var celllist = Jupyter.notebook.get_selected_cells();for (var i = 0;i<celllist.length;i++){celllist[i].element.children()[0].setAttribute(\"style\",\"background-color:pink;\");}"
};
var asnippet = {'type':'snippet',
'title':'Python snippet',
//Use double quotes around each line of code.
'data':["# A comment","print('Hello World!')"]
};
var acompsnippet = {'type':'computedsnippet',
'title':'Computed snippet',
//Use double quotes around the line of valid javascript.
'data':"'# The time is '+Date()"
};
var asubmenu = {'type':'submenu',
'title': 'SubMenu',
'data':[aurl, anaction]
};
var menu = {'type':'menu',
'title':'Test',
'data':[aurl,anaction, asubmenu, asnippet, acompsnippet]
};
JPSLMenus.build(menu);
}
```
* You can have computed snippets call functions you define. Again, it
is recommended that they be isolated from the global namespace by
defining them the same way as your `createMenu()` function. The data
line for such a snippet would
read `'data': "NameOfYourModule.NameOfSnippetCreationCode()"`. See
the example of the test code embedded in `js\menu.js` within this
module.
2. Add code to your module's `__init__.py` file to import the JPSLMenus
module and load the javascript for your menu. If your module only
creates menus, your init file may not contain anything but the code
suggested.
```
import JPSLMenus # This will embed the javascript menu resources in the output
# of the cell in which you import your module.
######
# Install your js files
######
import os
from IPython.display import display, HTML, Javascript
#Locate package directory
mydir=os.path.dirname(__file__) #absolute path to directory containing this file.
#load the supporting javascript
tempJSfile=open(os.path.join(mydir,'js','menu.js'))
tempscript='<script type="text/javascript">'
tempscript+=tempJSfile.read()+'</script>'
tempJSfile.close()
display(HTML(tempscript))
del tempJSfile
del tempscript
del mydir
# Call your menu creation code
jstr = 'NameOfYourModule.createMenu();'
display(Javascript(jstr))
del display
del HTML
del Javascript
del os
```
3. Make sure that `setup.py` or the equivalent for you module includes
`JPSLMenus` in its requirements.
## Create a menu from within a notebook
1. In a python code cell issue the command `import JPSLMenus`.
2. In another cell input the javascript to generate your menu. The
menu creation function can look just like the one suggested above for a
module. However, you have to call it within the same cell to create the
menu. Example:
```
%%javascript
let NameOfYourModule = new Object();
NameOfYourModule.createMenu = function(){
var aurl={'type':'url',
'title':'Lewis Structure Tutorial',
'data':'https://cms.gutow.uwosh.edu/Gutow/tutorials/lewis-structure-tutorial'
};
var anaction ={'type':'action',
'title':'Flag selected cells in pink',
'data':"var celllist = Jupyter.notebook.get_selected_cells();for (var i = 0;i<celllist.length;i++){celllist[i].element.children()[0].setAttribute(\"style\",\"background-color:pink;\");}"
};
var asnippet = {'type':'snippet',
'title':'Python snippet',
//Use double quotes around each line of code.
'data':["# A comment","print('Hello World!')"]
};
var acompsnippet = {'type':'computedsnippet',
'title':'Computed snippet',
//Use double quotes around the line of valid javascript.
'data':"'# The time is '+Date()"
};
var asubmenu = {'type':'submenu',
'title': 'SubMenu',
'data':[aurl, anaction]
};
var menu = {'type':'menu',
'title':'Test',
'data':[aurl,anaction, asubmenu, asnippet, acompsnippet]
};
JPSLMenus.build(menu);
}
NameOfYourModule.createMenu()
```
## Installation
1. This module is best installed in a virtual environment using pip.
2. If not installed, install pipenv:`$ pip3 install --user pipenv`. You may
need to add `~/.local/bin` to your `PATH` to make `pipenv`
available in your command shell. More discussion:
[The Hitchhiker's Guide to Python](https://docs.python-guide.org/dev/virtualenvs/).
1. Navigate to the directory where this package will be installed.
1. Start a shell in the environment `$ pipenv shell`.
1. Install using pip.
1. `$ pip install JPSLMenus`. This will install
Jupyter into the same virtual
environment if you do not already have it on your machine. If Jupyter is already
installed the virtual environment will use the existing installation. This takes
a long time on a Raspberry Pi. It will not run on a 3B+ without at least 1 GB of
swap. See: [Build Jupyter on a Pi
](https://www.uwosh.edu/facstaff/gutow/computer-and-programming-how-tos/installing-jupyter-on-raspberrian).
2. Still within the environment shell test this by starting jupyter
`$ jupyter notebook`. Jupyter should launch in your browser.
1. Open a new notebook using the default (Python 3) kernel.
1. In the first cell import the JPSLMenus module:
`import JPSLMenus`.
1. To try: copy the
[example menu creation javascript code](#create-a-menu-from-within-a-notebook)
into a code cell and run it.
## Change Log
* 0.5.0 Working version with basic documentation.
* 0.1.0 first version that is importable.
## [This software is distributed under the GNU V3 license](https://gnu.org/licenses)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Copyright - Jonathan Gutow, 2022.
Raw data
{
"_id": null,
"home_page": "https://github.com/JupyterPhysSciLab/JPSLMenus",
"name": "JPSLMenus",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "",
"author": "Jonathan Gutow",
"author_email": "gutow@uwosh.edu",
"download_url": "https://files.pythonhosted.org/packages/82/40/c6f2a56e435ccf8784808f3674266b2c6439dddd01cdc434de0481dae8f9/JPSLMenus-0.5.0.tar.gz",
"platform": null,
"description": "# JPSLMenus\n[Introduction](#introduction) |\n[Create Menu with a module](#create-a-menu-on-import-of-a-python-module) |\n[Create Menu within a Notebook](#create-a-menu-from-within-a-notebook) |\n[Installation](#installation) | [Change Log](#change-log) |\n[License](#this-software-is-distributed-under-the-gnu-v3-licensehttpsgnuorglicenses)\n\n## Introduction\n\nThis package contains utilities for building hierarchical menus that appear in \nthe Jupyter notebook menu bar. Unlike extensions, these menus can be added \nusing python import statements, so only appear in notebooks where the\nmodule(s) that creates them are imported.\n\nThe expectation is that *JPSLMenus* will be imported into the notebook by \nother modules when they are imported so that each module can use these \njavascript menu creation tools to construct their own menus. It is also \npossible to create a menu on-the-fly from javascript in a code cell \n([see below](#create-a-menu-from-within-a-notebook)).\n\n## Create a menu on import of a python module\n(NOTE: below may need modifying to work with a slow connection. Maybe use \n`promise` to wait until the object `JPSLMenus` is defined?)\n\n1. Create a javascript file containing a menu creation function that defines \n all menu elements, the menu structure and calls `JPSLMenus.build(menu)`:\n * Menu elements are defined by the following template:\n ```\n var item = {'type':'url|action|snippet|computedsnippet|submenu|menu',\n 'title':'String that will appear in menu',\n 'data': \\\\depends on type\n \\\\ url: \"string url\"\n \\\\ action: \"single line of valid javascript\"\n \\\\ snippet: [\"code line 1\",\"code line 2\"...]\n \\\\ computedsnippet: \"single line of valid javascript\"\n \\\\ that returns a string representation of the \n \\\\ snippet to insert.\n \\\\ submenu: [item1, item2...] items can be submenus.\n \\\\ menu: [item1, item2...] items can be submenus.\n };\n ```\n * Only one item of type menu should be passed to the build function. It \n will pull in each item as defined in the data array for the menu.\n * To minimize possible namespace collisions it is suggested that you \n build your menu creation function as in the following example.\n ```\n let NameOfYourModule = new Object();\n \n NameOfYourModule.createMenu = function(){\n var aurl={'type':'url',\n 'title':'Lewis Structure Tutorial',\n 'data':'https://cms.gutow.uwosh.edu/Gutow/tutorials/lewis-structure-tutorial'\n };\n var anaction ={'type':'action',\n 'title':'Flag selected cells in pink',\n 'data':\"var celllist = Jupyter.notebook.get_selected_cells();for (var i = 0;i<celllist.length;i++){celllist[i].element.children()[0].setAttribute(\\\"style\\\",\\\"background-color:pink;\\\");}\"\n };\n var asnippet = {'type':'snippet',\n 'title':'Python snippet',\n //Use double quotes around each line of code.\n 'data':[\"# A comment\",\"print('Hello World!')\"]\n };\n var acompsnippet = {'type':'computedsnippet',\n 'title':'Computed snippet',\n //Use double quotes around the line of valid javascript.\n 'data':\"'# The time is '+Date()\"\n };\n var asubmenu = {'type':'submenu',\n 'title': 'SubMenu',\n 'data':[aurl, anaction]\n };\n var menu = {'type':'menu',\n 'title':'Test',\n 'data':[aurl,anaction, asubmenu, asnippet, acompsnippet]\n };\n JPSLMenus.build(menu);\n }\n ```\n * You can have computed snippets call functions you define. Again, it \n is recommended that they be isolated from the global namespace by \n defining them the same way as your `createMenu()` function. The data \n line for such a snippet would\n read `'data': \"NameOfYourModule.NameOfSnippetCreationCode()\"`. See \n the example of the test code embedded in `js\\menu.js` within this \n module.\n2. Add code to your module's `__init__.py` file to import the JPSLMenus \n module and load the javascript for your menu. If your module only \n creates menus, your init file may not contain anything but the code \n suggested.\n ```\n import JPSLMenus # This will embed the javascript menu resources in the output\n # of the cell in which you import your module.\n ######\n # Install your js files\n ######\n import os\n from IPython.display import display, HTML, Javascript\n \n #Locate package directory\n mydir=os.path.dirname(__file__) #absolute path to directory containing this file.\n \n #load the supporting javascript\n tempJSfile=open(os.path.join(mydir,'js','menu.js'))\n tempscript='<script type=\"text/javascript\">'\n tempscript+=tempJSfile.read()+'</script>'\n tempJSfile.close()\n display(HTML(tempscript))\n del tempJSfile\n del tempscript\n del mydir\n \n # Call your menu creation code\n jstr = 'NameOfYourModule.createMenu();'\n display(Javascript(jstr))\n del display\n del HTML\n del Javascript\n del os\n ```\n3. Make sure that `setup.py` or the equivalent for you module includes \n `JPSLMenus` in its requirements.\n\n## Create a menu from within a notebook\n\n1. In a python code cell issue the command `import JPSLMenus`.\n2. In another cell input the javascript to generate your menu. The \n menu creation function can look just like the one suggested above for a \n module. However, you have to call it within the same cell to create the \n menu. Example:\n ```\n %%javascript\n let NameOfYourModule = new Object();\n \n NameOfYourModule.createMenu = function(){\n var aurl={'type':'url',\n 'title':'Lewis Structure Tutorial',\n 'data':'https://cms.gutow.uwosh.edu/Gutow/tutorials/lewis-structure-tutorial'\n };\n var anaction ={'type':'action',\n 'title':'Flag selected cells in pink',\n 'data':\"var celllist = Jupyter.notebook.get_selected_cells();for (var i = 0;i<celllist.length;i++){celllist[i].element.children()[0].setAttribute(\\\"style\\\",\\\"background-color:pink;\\\");}\"\n };\n var asnippet = {'type':'snippet',\n 'title':'Python snippet',\n //Use double quotes around each line of code.\n 'data':[\"# A comment\",\"print('Hello World!')\"]\n };\n var acompsnippet = {'type':'computedsnippet',\n 'title':'Computed snippet',\n //Use double quotes around the line of valid javascript.\n 'data':\"'# The time is '+Date()\"\n };\n var asubmenu = {'type':'submenu',\n 'title': 'SubMenu',\n 'data':[aurl, anaction]\n };\n var menu = {'type':'menu',\n 'title':'Test',\n 'data':[aurl,anaction, asubmenu, asnippet, acompsnippet]\n };\n JPSLMenus.build(menu);\n }\n NameOfYourModule.createMenu()\n ```\n## Installation\n\n1. This module is best installed in a virtual environment using pip.\n2. If not installed, install pipenv:`$ pip3 install --user pipenv`. You may\nneed to add `~/.local/bin` to your `PATH` to make `pipenv`\navailable in your command shell. More discussion: \n[The Hitchhiker's Guide to Python](https://docs.python-guide.org/dev/virtualenvs/).\n1. Navigate to the directory where this package will be installed.\n1. Start a shell in the environment `$ pipenv shell`.\n1. Install using pip.\n 1. `$ pip install JPSLMenus`. This will install \n Jupyter into the same virtual\n environment if you do not already have it on your machine. If Jupyter is already\n installed the virtual environment will use the existing installation. This takes\n a long time on a Raspberry Pi. It will not run on a 3B+ without at least 1 GB of\n swap. See: [Build Jupyter on a Pi\n ](https://www.uwosh.edu/facstaff/gutow/computer-and-programming-how-tos/installing-jupyter-on-raspberrian).\n 2. Still within the environment shell test this by starting jupyter\n`$ jupyter notebook`. Jupyter should launch in your browser.\n 1. Open a new notebook using the default (Python 3) kernel.\n 1. In the first cell import the JPSLMenus module:\n `import JPSLMenus`.\n 1. To try: copy the\n [example menu creation javascript code](#create-a-menu-from-within-a-notebook)\n into a code cell and run it.\n\n## Change Log\n\n* 0.5.0 Working version with basic documentation.\n* 0.1.0 first version that is importable.\n\n## [This software is distributed under the GNU V3 license](https://gnu.org/licenses)\nThis program is free software: you can redistribute it and/or modify\n it under the terms of the GNU General Public License as published by\n the Free Software Foundation, either version 3 of the License, or\n (at your option) any later version.\n This program is distributed in the hope that it will be useful,\n but WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n GNU General Public License for more details.\n\nCopyright - Jonathan Gutow, 2022. \n",
"bugtrack_url": null,
"license": "GPL-3.0+",
"summary": "Tools to build menus",
"version": "0.5.0",
"project_urls": {
"Homepage": "https://github.com/JupyterPhysSciLab/JPSLMenus"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "a79d842038696c5b9048e11b1c93bcb83f04ac8593f87cd5e14bde16593801b0",
"md5": "b35c24f327709aa99a7d3669c2dc49c8",
"sha256": "65c07a466cca94732838d1efab967cbb19bbe1947b99b97b3f96687b21372420"
},
"downloads": -1,
"filename": "JPSLMenus-0.5.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b35c24f327709aa99a7d3669c2dc49c8",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 7298,
"upload_time": "2022-05-26T01:24:12",
"upload_time_iso_8601": "2022-05-26T01:24:12.669769Z",
"url": "https://files.pythonhosted.org/packages/a7/9d/842038696c5b9048e11b1c93bcb83f04ac8593f87cd5e14bde16593801b0/JPSLMenus-0.5.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8240c6f2a56e435ccf8784808f3674266b2c6439dddd01cdc434de0481dae8f9",
"md5": "2c6b0071aa77cbc70f846cb5c7ed69a0",
"sha256": "458c612f0011e78e22a021de10571085762a77ad68203b01f2b61580cafbdbb7"
},
"downloads": -1,
"filename": "JPSLMenus-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "2c6b0071aa77cbc70f846cb5c7ed69a0",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 6790,
"upload_time": "2022-05-26T01:24:14",
"upload_time_iso_8601": "2022-05-26T01:24:14.395896Z",
"url": "https://files.pythonhosted.org/packages/82/40/c6f2a56e435ccf8784808f3674266b2c6439dddd01cdc434de0481dae8f9/JPSLMenus-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2022-05-26 01:24:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "JupyterPhysSciLab",
"github_project": "JPSLMenus",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "jpslmenus"
}