From 5f81754136d24f6b8922261c085dc215a67afb29 Mon Sep 17 00:00:00 2001 From: Tim Huegerich Date: Mon, 21 Nov 2022 12:58:35 -0600 Subject: [PATCH] Fix magics; add README instructions --- README.md | 93 +++++++++++++++++++++++++++++++++++++- nbs/03_magics.ipynb | 7 +-- nbs/index.ipynb | 107 +++++++++++++++++++++++++++++++++++++++----- nbstata/magics.py | 5 ++- 4 files changed, 194 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 883381d..6b13e99 100644 --- a/README.md +++ b/README.md @@ -3,15 +3,104 @@ nbstata +Requires Stata 17 or above because it uses +[pystata](https://www.stata.com/python/pystata/). Consider +[stata_kernel](https://github.com/kylebarron/stata_kernel) instead if +you have an older version of Stata. + ## Install +To install, run: + ``` sh pip install nbstata +python -m nbstata.install [--sys-prefix] [--prefix] [--conf-file] +``` + +Include `--sys-prefix` if you are installing `nbstata` in a multi-user +environment, or `--prefix` if you want to specify a path yourself. + +At runtime, `nbstata` will try to determine the location of your Stata +installation. You can create a configuration file to preempt this +detection with the `--conf-file` option. Even if you do not include this +option, the configuration file will still be created if the installer +cannot find any Stata installation. + +The location of the configuration file is: + +- `[prefix]/etc/nbstata.conf` if `--sys-prefix` or `--prefix` is + specified. +- `~/.nbstata.conf` otherwise. + +If a configuration file exists in both locations, the user version takes +precedence. + +Syntax highlighting is the same as `stata_kernel`: + +``` sh +conda install nodejs -c conda-forge --repodata-fn=repodata.json +jupyter labextension install jupyterlab-stata-highlight ``` -## How to use +## Configuration + +The following settings are permitted inside the configuration file: + +- `stata_dir`: Stata installation directory. +- `edition`: Stata edition. Acceptable values are ‘be’, ‘se’ and ‘mp’. + Default is ‘be’. +- `graph_format`: Graph format. Acceptable values are ‘png’, ‘pdf’, + ‘svg’ and ‘pystata’. Specify the last option if you want to use + `nbstata`‘s setting. Default is ’png’. +- `echo`: controls the echo of commands: + - ‘True’: the kernel will echo all commands. + - ‘False’: the kernel will not echo single-line commands. + - ‘None’: the kernel will not echo any command. + + Default is ‘None’. +- `splash`: controls display of the splash message during Stata startup. + Default is ‘False’. +- `missing`: What should be displayed in the output of the `*%browse` + magic for a missing value. Default is ‘.’, following Stata. To defer + to pandas’ format for `NA`, specify ‘pandas’. + +Settings must be under the title `[nbstata]`. Example: + + [nbstata] + stata_dir = /opt/stata + edition = mp + graph_format = svg + echo = True + splash = False + +#### Default Graph Format + +Both `pystata` and `stata_kernel` default to the SVG image format. +`nbstata` defaults to the PNG image format instead for several reasons: + +- Jupyter does not show SVG images from untrusted notebooks ([link + 1](https://stackoverflow.com/questions/68398033/svg-figures-hidden-in-jupyterlab-after-some-time)). +- Notebooks with empty cells are untrusted ([link + 2](https://github.com/jupyterlab/jupyterlab/issues/9765)). +- SVG images cannot be copied and pasted directly into Word or + PowerPoint. + +### Magics + +Magics are commands that only work in `nbstata` and are not part of +Stata’s syntax. Magics normally start with `%`, but this will cause +errors when the notebook is exported and run as a Stata script. As an +alternative, you can prefix the magic name with `*%`, which will simply +be treated by Stata as a single-line comment. + +`nbstata` currently supports the following magics: -Under construction +| Magic | Description | Full Syntax | +|:------------|:--------------------------------------|:----------------------------------------| +| `*%browse` | View dataset | `*%browse [-h] [N] [varlist] [if] [in]` | +| `*%help` | Display a help file in rich text | `*%help [-h] command_or_topic_name` | +| `*%noecho` | Suppress echo in current cell | `*%noecho` | +| `*%quietly` | Suppress all output from current cell | `*%quietly` | ## Contributing diff --git a/nbs/03_magics.ipynb b/nbs/03_magics.ipynb index c0a2a50..45946a8 100644 --- a/nbs/03_magics.ipynb +++ b/nbs/03_magics.ipynb @@ -44,7 +44,8 @@ "import re\n", "import urllib\n", "from pkg_resources import resource_filename\n", - "import numpy as np" + "import numpy as np\n", + "from bs4 import BeautifulSoup as bs" ] }, { @@ -136,8 +137,8 @@ " args = parse_code_if_in(code)\n", " \n", " # If and in statements\n", - " sel_var = SelVar(args['if'])\n", - " start,end = InVar(args['in'])\n", + " sel_var = Selectvar(args['if'])\n", + " start,end = in_range(args['in'])\n", " \n", " vargs = [c.strip() for c in args['code'].split(' ') if c]\n", "\n", diff --git a/nbs/index.ipynb b/nbs/index.ipynb index 35c9e97..916714e 100644 --- a/nbs/index.ipynb +++ b/nbs/index.ipynb @@ -22,7 +22,11 @@ { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "Requires Stata 17 or above because it uses [pystata](https://www.stata.com/python/pystata/).\n", + "Consider [stata_kernel](https://github.com/kylebarron/stata_kernel) instead if you have an \n", + "older version of Stata. " + ] }, { "cell_type": "markdown", @@ -35,8 +39,33 @@ "cell_type": "markdown", "metadata": {}, "source": [ + "To install, run:\n", + "\n", "```sh\n", "pip install nbstata\n", + "python -m nbstata.install [--sys-prefix] [--prefix] [--conf-file]\n", + "```\n", + "\n", + "Include `--sys-prefix` if you are installing `nbstata` in a multi-user environment,\n", + "or `--prefix` if you want to specify a path yourself.\n", + "\n", + "At runtime, `nbstata` will try to determine the location of your Stata installation. \n", + "You can create a configuration file to preempt this detection with the `--conf-file` option.\n", + "Even if you do not include this option, the configuration file will still be created if the \n", + "installer cannot find any Stata installation.\n", + "\n", + "The location of the configuration file is:\n", + "\n", + "- `[prefix]/etc/nbstata.conf` if `--sys-prefix` or `--prefix` is specified.\n", + "- `~/.nbstata.conf` otherwise.\n", + "\n", + "If a configuration file exists in both locations, the user version takes precedence. \n", + "\n", + "Syntax highlighting is the same as `stata_kernel`:\n", + "\n", + "```sh\n", + "conda install nodejs -c conda-forge --repodata-fn=repodata.json\n", + "jupyter labextension install jupyterlab-stata-highlight\n", "```" ] }, @@ -44,29 +73,85 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## How to use" + "## Configuration" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "Under construction" + "The following settings are permitted inside the configuration file:\n", + "\n", + "- `stata_dir`: Stata installation directory.\n", + "- `edition`: Stata edition. Acceptable values are 'be', 'se' and 'mp'.\n", + " Default is 'be'.\n", + "- `graph_format`: Graph format. Acceptable values are 'png', 'pdf', 'svg' and 'pystata'.\n", + " Specify the last option if you want to use `nbstata`'s setting. Default is 'png'. \n", + "- `echo`: controls the echo of commands:\n", + " - 'True': the kernel will echo all commands. \n", + " - 'False': the kernel will not echo single-line commands.\n", + " - 'None': the kernel will not echo any command. \n", + "\n", + " Default is 'None'.\n", + "- `splash`: controls display of the splash message during Stata startup. Default is 'False'.\n", + "- `missing`: What should be displayed in the output of the `*%browse` magic for a missing value. Default is '.', following Stata. To defer to pandas' format for `NA`, specify 'pandas'.\n", + "\n", + "Settings must be under the title `[nbstata]`. Example:\n", + "\n", + "```\n", + "[nbstata]\n", + "stata_dir = /opt/stata\n", + "edition = mp\n", + "graph_format = svg\n", + "echo = True\n", + "splash = False\n", + "```" ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "#### Default Graph Format" + ] }, { - "cell_type": "code", - "execution_count": null, + "cell_type": "markdown", "metadata": {}, - "outputs": [], - "source": [] + "source": [ + "Both `pystata` and `stata_kernel` default to the SVG image format. \n", + "`nbstata` defaults to the PNG image format instead for several reasons:\n", + "\n", + "- Jupyter does not show SVG images from untrusted notebooks ([link 1](https://stackoverflow.com/questions/68398033/svg-figures-hidden-in-jupyterlab-after-some-time)).\n", + "- Notebooks with empty cells are untrusted ([link 2](https://github.com/jupyterlab/jupyterlab/issues/9765)).\n", + "- SVG images cannot be copied and pasted directly into Word or PowerPoint." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Magics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Magics are commands that only work in `nbstata` and are not part of Stata's syntax. \n", + "Magics normally start with `%`, but this will cause errors when the notebook\n", + "is exported and run as a Stata script. As an alternative, you can prefix the \n", + "magic name with `*%`, which will simply be treated by Stata as a single-line comment.\n", + "\n", + "`nbstata` currently supports the following magics:\n", + "\n", + "| Magic | Description | Full Syntax |\n", + "| :-- | :-- | :-- |\n", + "| `*%browse` | View dataset | `*%browse [-h] [N] [varlist] [if] [in]` |\n", + "| `*%help` | Display a help file in rich text| `*%help [-h] command_or_topic_name` |\n", + "| `*%noecho` | Suppress echo in current cell | `*%noecho` |\n", + "| `*%quietly` | Suppress all output from current cell | `*%quietly` |" + ] }, { "cell_type": "markdown", diff --git a/nbstata/magics.py b/nbstata/magics.py index b491a68..113cb0e 100644 --- a/nbstata/magics.py +++ b/nbstata/magics.py @@ -11,6 +11,7 @@ import urllib from pkg_resources import resource_filename import numpy as np +from bs4 import BeautifulSoup as bs # %% ../nbs/03_magics.ipynb 4 def print_kernel(msg, kernel): @@ -88,8 +89,8 @@ def magic_browse(self,code,kernel,cell): args = parse_code_if_in(code) # If and in statements - sel_var = SelVar(args['if']) - start,end = InVar(args['in']) + sel_var = Selectvar(args['if']) + start,end = in_range(args['in']) vargs = [c.strip() for c in args['code'].split(' ') if c]