diff --git a/nbs/02_stata.ipynb b/nbs/02_stata.ipynb index c1b4512..0b96b47 100644 --- a/nbs/02_stata.ipynb +++ b/nbs/02_stata.ipynb @@ -137,7 +137,7 @@ "id": "6b79b383", "metadata": {}, "source": [ - "[https://www.stata.com/python/api17/Macro.html#sfi.Macro.setLocal](https://www.stata.com/python/api17/Macro.html#sfi.Macro.setLocal)" + "[https://www.stata.com/python/api17/Macro.html#sfi.Macro.getGlobal](https://www.stata.com/python/api17/Macro.html#sfi.Macro.getGlobal)" ] }, { @@ -153,6 +153,27 @@ " return sfi.Macro.getGlobal(name)" ] }, + { + "cell_type": "markdown", + "id": "092d242f", + "metadata": {}, + "source": [ + "[https://www.stata.com/python/api17/Macro.html#sfi.Macro.setGlobal](https://www.stata.com/python/api17/Macro.html#sfi.Macro.setGlobal)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "18638e7f", + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "def set_global(name):\n", + " import sfi\n", + " return sfi.Macro.setGlobal(name, value)" + ] + }, { "cell_type": "markdown", "id": "fb3c1b96", @@ -636,7 +657,7 @@ "0\n", "Elapsed time: 0.0001 seconds\n", "0\n", - "Elapsed time: 0.0585 seconds\n" + "Elapsed time: 0.0484 seconds\n" ] } ], @@ -1453,9 +1474,21 @@ ], "metadata": { "kernelspec": { - "display_name": "python3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" } }, "nbformat": 4, diff --git a/nbs/14_kernel.ipynb b/nbs/14_kernel.ipynb index 04652fc..5d8a1be 100644 --- a/nbs/14_kernel.ipynb +++ b/nbs/14_kernel.ipynb @@ -47,6 +47,7 @@ "#| export\n", "from nbstata.config import Config\n", "from nbstata.misc_utils import print_red\n", + "from nbstata.stata import set_global\n", "from nbstata.stata_more import user_expression\n", "from nbstata.inspect import get_inspect\n", "from nbstata.stata_session import StataSession\n", @@ -93,6 +94,14 @@ " },\n", " ]\n", "\n", + " # for communication from Quarto\n", + " def comm_open(self, stream, ident, msg):\n", + " msg = msg['content']\n", + " if msg['target_name'] == \"quarto_kernel_setup\":\n", + " for key, value in msg['data']['options']['params'].items():\n", + " set_global(key, value)\n", + " # here, msg['data']['options'] has all quarto setup options\n", + " \n", " def __init__(self, **kwargs):\n", " super().__init__(**kwargs)\n", " self.stata_ready = False\n", @@ -102,7 +111,8 @@ " self.nbstata_config = Config()\n", " self.stata_session = StataSession()\n", " self.completions = CompletionsManager(self.stata_session)\n", - " self.inspect_output = \"\"" + " self.inspect_output = \"\"\n", + " self.shell_handlers['comm_open'] = self.comm_open" ] }, { @@ -536,6 +546,18 @@ " return _handle_stata_import_error(err, silent, self.execution_count)\n", " \n", " self.shell.execution_count += 1\n", + " is_setup_cell = code.strip() == \"56ed7992-3715-4d16-a6c0-e5f98c12799d\" \n", + " if is_setup_cell:\n", + " code = \"\"\n", + " # If this is a setup cell, quarto will ignore the output\n", + " # (except for the metadata). Still, `execute_result` needs\n", + " # something to send, so we send an empty string\n", + " self.send_response(self.iopub_socket, 'execute_result', {\n", + " 'data': {\"text/plain\": \"\"}, \n", + " 'metadata': {'quarto': {'daemonize': False}},\n", + " 'execution_count': self.shell.execution_count,\n", + " })\n", + " \n", " code_cell = Cell(self, code, silent)\n", " try:\n", " code_cell.run()\n", @@ -644,34 +666,7 @@ "cell_type": "code", "execution_count": null, "metadata": {}, - "outputs": [ - { - "ename": "error", - "evalue": "multiple repeat at position 3", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31merror\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[31], line 2\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;66;03m#| hide\u001b[39;00m\n\u001b[1;32m----> 2\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnbdev\u001b[39;00m; \u001b[43mnbdev\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mnbdev_export\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\fastcore\\script.py:110\u001b[0m, in \u001b[0;36mcall_parse.._f\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 107\u001b[0m \u001b[38;5;129m@wraps\u001b[39m(func)\n\u001b[0;32m 108\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_f\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[0;32m 109\u001b[0m mod \u001b[38;5;241m=\u001b[39m inspect\u001b[38;5;241m.\u001b[39mgetmodule(inspect\u001b[38;5;241m.\u001b[39mcurrentframe()\u001b[38;5;241m.\u001b[39mf_back)\n\u001b[1;32m--> 110\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m mod: \u001b[38;5;28;01mreturn\u001b[39;00m func(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m 111\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m SCRIPT_INFO\u001b[38;5;241m.\u001b[39mfunc \u001b[38;5;129;01mand\u001b[39;00m mod\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;241m==\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__main__\u001b[39m\u001b[38;5;124m\"\u001b[39m: SCRIPT_INFO\u001b[38;5;241m.\u001b[39mfunc \u001b[38;5;241m=\u001b[39m func\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\n\u001b[0;32m 112\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(sys\u001b[38;5;241m.\u001b[39margv)\u001b[38;5;241m>\u001b[39m\u001b[38;5;241m1\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m sys\u001b[38;5;241m.\u001b[39margv[\u001b[38;5;241m1\u001b[39m]\u001b[38;5;241m==\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m: sys\u001b[38;5;241m.\u001b[39margv\u001b[38;5;241m.\u001b[39mpop(\u001b[38;5;241m1\u001b[39m)\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\doclinks.py:151\u001b[0m, in \u001b[0;36mnbdev_export\u001b[1;34m(path, procs, **kwargs)\u001b[0m\n\u001b[0;32m 149\u001b[0m procs \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28mgetattr\u001b[39m(nbdev\u001b[38;5;241m.\u001b[39mexport, p) \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m L(procs)]\n\u001b[0;32m 150\u001b[0m files \u001b[38;5;241m=\u001b[39m nbglob(path\u001b[38;5;241m=\u001b[39mpath, as_path\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\u001b[38;5;241m.\u001b[39msorted(\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mname\u001b[39m\u001b[38;5;124m'\u001b[39m)\n\u001b[1;32m--> 151\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m f \u001b[38;5;129;01min\u001b[39;00m files: \u001b[43mnb_export\u001b[49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprocs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mprocs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 152\u001b[0m add_init(get_config()\u001b[38;5;241m.\u001b[39mlib_path)\n\u001b[0;32m 153\u001b[0m _build_modidx()\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\export.py:73\u001b[0m, in \u001b[0;36mnb_export\u001b[1;34m(nbname, lib_path, procs, debug, mod_maker, name)\u001b[0m\n\u001b[0;32m 71\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m lib_path \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m: lib_path \u001b[38;5;241m=\u001b[39m get_config()\u001b[38;5;241m.\u001b[39mlib_path\n\u001b[0;32m 72\u001b[0m exp \u001b[38;5;241m=\u001b[39m ExportModuleProc()\n\u001b[1;32m---> 73\u001b[0m nb \u001b[38;5;241m=\u001b[39m \u001b[43mNBProcessor\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnbname\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43m[\u001b[49m\u001b[43mexp\u001b[49m\u001b[43m]\u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43mL\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprocs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdebug\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdebug\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 74\u001b[0m nb\u001b[38;5;241m.\u001b[39mprocess()\n\u001b[0;32m 75\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m mod,cells \u001b[38;5;129;01min\u001b[39;00m exp\u001b[38;5;241m.\u001b[39mmodules\u001b[38;5;241m.\u001b[39mitems():\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\process.py:97\u001b[0m, in \u001b[0;36mNBProcessor.__init__\u001b[1;34m(self, path, procs, nb, debug, rm_directives, process)\u001b[0m\n\u001b[0;32m 95\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnb \u001b[38;5;241m=\u001b[39m read_nb(path) \u001b[38;5;28;01mif\u001b[39;00m nb \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;28;01melse\u001b[39;00m nb\n\u001b[0;32m 96\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mlang \u001b[38;5;241m=\u001b[39m nb_lang(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnb)\n\u001b[1;32m---> 97\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m cell \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnb\u001b[38;5;241m.\u001b[39mcells: cell\u001b[38;5;241m.\u001b[39mdirectives_ \u001b[38;5;241m=\u001b[39m \u001b[43mextract_directives\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcell\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mremove\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrm_directives\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlang\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlang\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 98\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprocs \u001b[38;5;241m=\u001b[39m _mk_procs(procs, nb\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mnb)\n\u001b[0;32m 99\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdebug,\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mrm_directives \u001b[38;5;241m=\u001b[39m debug,rm_directives\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\process.py:69\u001b[0m, in \u001b[0;36mextract_directives\u001b[1;34m(cell, remove, lang)\u001b[0m\n\u001b[0;32m 67\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mextract_directives\u001b[39m(cell, remove\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, lang\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mpython\u001b[39m\u001b[38;5;124m'\u001b[39m):\n\u001b[0;32m 68\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mTake leading comment directives from lines of code in `ss`, remove `#|`, and split\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m---> 69\u001b[0m dirs,code \u001b[38;5;241m=\u001b[39m \u001b[43m_partition_cell\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcell\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlang\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 70\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m dirs: \u001b[38;5;28;01mreturn\u001b[39;00m {}\n\u001b[0;32m 71\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m remove:\n\u001b[0;32m 72\u001b[0m \u001b[38;5;66;03m# Leave Quarto directives and cell magic in place for later processing\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\process.py:63\u001b[0m, in \u001b[0;36m_partition_cell\u001b[1;34m(cell, lang)\u001b[0m\n\u001b[0;32m 61\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m cell\u001b[38;5;241m.\u001b[39msource: \u001b[38;5;28;01mreturn\u001b[39;00m [],[]\n\u001b[0;32m 62\u001b[0m lines \u001b[38;5;241m=\u001b[39m cell\u001b[38;5;241m.\u001b[39msource\u001b[38;5;241m.\u001b[39msplitlines(\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[1;32m---> 63\u001b[0m first_code \u001b[38;5;241m=\u001b[39m \u001b[43mfirst_code_ln\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlines\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlang\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mlang\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 64\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m lines[:first_code],lines[first_code:]\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\process.py:57\u001b[0m, in \u001b[0;36mfirst_code_ln\u001b[1;34m(code_list, re_pattern, lang)\u001b[0m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mget first line number where code occurs, where `code_list` is a list of code\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m re_pattern \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m: re_pattern \u001b[38;5;241m=\u001b[39m _dir_pre(lang)\n\u001b[1;32m---> 57\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfirst\u001b[49m\u001b[43m(\u001b[49m\u001b[43mi\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mi\u001b[49m\u001b[43m,\u001b[49m\u001b[43mo\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43menumerate\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mcode_list\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mo\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mstrip\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m!=\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mand\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mre\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmatch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mre_pattern\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mo\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mand\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43m_cell_mgc\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmatch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mo\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\fastcore\\basics.py:660\u001b[0m, in \u001b[0;36mfirst\u001b[1;34m(x, f, negate, **kwargs)\u001b[0m\n\u001b[0;32m 658\u001b[0m x \u001b[38;5;241m=\u001b[39m \u001b[38;5;28miter\u001b[39m(x)\n\u001b[0;32m 659\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m f: x \u001b[38;5;241m=\u001b[39m filter_ex(x, f\u001b[38;5;241m=\u001b[39mf, negate\u001b[38;5;241m=\u001b[39mnegate, gen\u001b[38;5;241m=\u001b[39m\u001b[38;5;28;01mTrue\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m--> 660\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mnext\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mx\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\site-packages\\nbdev\\process.py:57\u001b[0m, in \u001b[0;36m\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m 55\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mget first line number where code occurs, where `code_list` is a list of code\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[0;32m 56\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m re_pattern \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m: re_pattern \u001b[38;5;241m=\u001b[39m _dir_pre(lang)\n\u001b[1;32m---> 57\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m first(i \u001b[38;5;28;01mfor\u001b[39;00m i,o \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(code_list) \u001b[38;5;28;01mif\u001b[39;00m o\u001b[38;5;241m.\u001b[39mstrip() \u001b[38;5;241m!=\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124m'\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[43mre\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmatch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mre_pattern\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mo\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m _cell_mgc\u001b[38;5;241m.\u001b[39mmatch(o))\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\re.py:190\u001b[0m, in \u001b[0;36mmatch\u001b[1;34m(pattern, string, flags)\u001b[0m\n\u001b[0;32m 187\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mmatch\u001b[39m(pattern, string, flags\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0\u001b[39m):\n\u001b[0;32m 188\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Try to apply the pattern at the start of the string, returning\u001b[39;00m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;124;03m a Match object, or None if no match was found.\"\"\"\u001b[39;00m\n\u001b[1;32m--> 190\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_compile\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpattern\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mflags\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241m.\u001b[39mmatch(string)\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\re.py:303\u001b[0m, in \u001b[0;36m_compile\u001b[1;34m(pattern, flags)\u001b[0m\n\u001b[0;32m 301\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m sre_compile\u001b[38;5;241m.\u001b[39misstring(pattern):\n\u001b[0;32m 302\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mfirst argument must be string or compiled pattern\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m--> 303\u001b[0m p \u001b[38;5;241m=\u001b[39m \u001b[43msre_compile\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompile\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpattern\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mflags\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 304\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (flags \u001b[38;5;241m&\u001b[39m DEBUG):\n\u001b[0;32m 305\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(_cache) \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m _MAXCACHE:\n\u001b[0;32m 306\u001b[0m \u001b[38;5;66;03m# Drop the oldest item\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\sre_compile.py:788\u001b[0m, in \u001b[0;36mcompile\u001b[1;34m(p, flags)\u001b[0m\n\u001b[0;32m 786\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m isstring(p):\n\u001b[0;32m 787\u001b[0m pattern \u001b[38;5;241m=\u001b[39m p\n\u001b[1;32m--> 788\u001b[0m p \u001b[38;5;241m=\u001b[39m \u001b[43msre_parse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mparse\u001b[49m\u001b[43m(\u001b[49m\u001b[43mp\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mflags\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 789\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 790\u001b[0m pattern \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\sre_parse.py:955\u001b[0m, in \u001b[0;36mparse\u001b[1;34m(str, flags, state)\u001b[0m\n\u001b[0;32m 952\u001b[0m state\u001b[38;5;241m.\u001b[39mstr \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m\n\u001b[0;32m 954\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m--> 955\u001b[0m p \u001b[38;5;241m=\u001b[39m \u001b[43m_parse_sub\u001b[49m\u001b[43m(\u001b[49m\u001b[43msource\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstate\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mflags\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m&\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mSRE_FLAG_VERBOSE\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 956\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m Verbose:\n\u001b[0;32m 957\u001b[0m \u001b[38;5;66;03m# the VERBOSE flag was switched on inside the pattern. to be\u001b[39;00m\n\u001b[0;32m 958\u001b[0m \u001b[38;5;66;03m# on the safe side, we'll parse the whole thing again...\u001b[39;00m\n\u001b[0;32m 959\u001b[0m state \u001b[38;5;241m=\u001b[39m State()\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\sre_parse.py:444\u001b[0m, in \u001b[0;36m_parse_sub\u001b[1;34m(source, state, verbose, nested)\u001b[0m\n\u001b[0;32m 442\u001b[0m start \u001b[38;5;241m=\u001b[39m source\u001b[38;5;241m.\u001b[39mtell()\n\u001b[0;32m 443\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m--> 444\u001b[0m itemsappend(\u001b[43m_parse\u001b[49m\u001b[43m(\u001b[49m\u001b[43msource\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstate\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mverbose\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnested\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[0;32m 445\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mnested\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mand\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;129;43;01mnot\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mitems\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[0;32m 446\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m sourcematch(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m|\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m 447\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n", - "File \u001b[1;32m~\\AppData\\Local\\anaconda3\\envs\\Python2022-05a\\lib\\sre_parse.py:672\u001b[0m, in \u001b[0;36m_parse\u001b[1;34m(source, state, verbose, nested, first)\u001b[0m\n\u001b[0;32m 669\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m source\u001b[38;5;241m.\u001b[39merror(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnothing to repeat\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 670\u001b[0m source\u001b[38;5;241m.\u001b[39mtell() \u001b[38;5;241m-\u001b[39m here \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mlen\u001b[39m(this))\n\u001b[0;32m 671\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m item[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m] \u001b[38;5;129;01min\u001b[39;00m _REPEATCODES:\n\u001b[1;32m--> 672\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m source\u001b[38;5;241m.\u001b[39merror(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmultiple repeat\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 673\u001b[0m source\u001b[38;5;241m.\u001b[39mtell() \u001b[38;5;241m-\u001b[39m here \u001b[38;5;241m+\u001b[39m \u001b[38;5;28mlen\u001b[39m(this))\n\u001b[0;32m 674\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m item[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m0\u001b[39m] \u001b[38;5;129;01mis\u001b[39;00m SUBPATTERN:\n\u001b[0;32m 675\u001b[0m group, add_flags, del_flags, p \u001b[38;5;241m=\u001b[39m item[\u001b[38;5;241m0\u001b[39m][\u001b[38;5;241m1\u001b[39m]\n", - "\u001b[1;31merror\u001b[0m: multiple repeat at position 3" - ] - } - ], + "outputs": [], "source": [ "#| hide\n", "import nbdev; nbdev.nbdev_export()" @@ -680,9 +675,21 @@ ], "metadata": { "kernelspec": { - "display_name": "python3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" } }, "nbformat": 4, diff --git a/nbstata/_modidx.py b/nbstata/_modidx.py index 1013b0f..b47c4e9 100644 --- a/nbstata/_modidx.py +++ b/nbstata/_modidx.py @@ -127,6 +127,7 @@ 'nbstata.install.main': ('install.html#main', 'nbstata/install.py')}, 'nbstata.kernel': { 'nbstata.kernel.PyStataKernel': ('kernel.html#pystatakernel', 'nbstata/kernel.py'), 'nbstata.kernel.PyStataKernel.__init__': ('kernel.html#pystatakernel.__init__', 'nbstata/kernel.py'), + 'nbstata.kernel.PyStataKernel.comm_open': ('kernel.html#pystatakernel.comm_open', 'nbstata/kernel.py'), 'nbstata.kernel.PyStataKernel.do_complete': ('kernel.html#pystatakernel.do_complete', 'nbstata/kernel.py'), 'nbstata.kernel.PyStataKernel.do_execute': ('kernel.html#pystatakernel.do_execute', 'nbstata/kernel.py'), 'nbstata.kernel.PyStataKernel.do_history': ('kernel.html#pystatakernel.do_history', 'nbstata/kernel.py'), @@ -222,6 +223,7 @@ 'nbstata.stata.pwd': ('stata.html#pwd', 'nbstata/stata.py'), 'nbstata.stata.run_direct': ('stata.html#run_direct', 'nbstata/stata.py'), 'nbstata.stata.run_single': ('stata.html#run_single', 'nbstata/stata.py'), + 'nbstata.stata.set_global': ('stata.html#set_global', 'nbstata/stata.py'), 'nbstata.stata.set_local': ('stata.html#set_local', 'nbstata/stata.py'), 'nbstata.stata.stata_formatted': ('stata.html#stata_formatted', 'nbstata/stata.py'), 'nbstata.stata.variable_names': ('stata.html#variable_names', 'nbstata/stata.py')}, diff --git a/nbstata/kernel.py b/nbstata/kernel.py index 9a83788..568e83a 100644 --- a/nbstata/kernel.py +++ b/nbstata/kernel.py @@ -8,6 +8,7 @@ # %% ../nbs/14_kernel.ipynb 4 from .config import Config from .misc_utils import print_red +from .stata import set_global from .stata_more import user_expression from .inspect import get_inspect from .stata_session import StataSession @@ -40,6 +41,14 @@ class PyStataKernel(IPythonKernel): }, ] + # for communication from Quarto + def comm_open(self, stream, ident, msg): + msg = msg['content'] + if msg['target_name'] == "quarto_kernel_setup": + for key, value in msg['data']['options']['params'].items(): + set_global(key, value) + # here, msg['data']['options'] has all quarto setup options + def __init__(self, **kwargs): super().__init__(**kwargs) self.stata_ready = False @@ -50,6 +59,7 @@ def __init__(self, **kwargs): self.stata_session = StataSession() self.completions = CompletionsManager(self.stata_session) self.inspect_output = "" + self.shell_handlers['comm_open'] = self.comm_open # %% ../nbs/14_kernel.ipynb 8 @patch_to(PyStataKernel) @@ -161,6 +171,18 @@ def do_execute(self, code, silent, return _handle_stata_import_error(err, silent, self.execution_count) self.shell.execution_count += 1 + is_setup_cell = code.strip() == "56ed7992-3715-4d16-a6c0-e5f98c12799d" + if is_setup_cell: + code = "" + # If this is a setup cell, quarto will ignore the output + # (except for the metadata). Still, `execute_result` needs + # something to send, so we send an empty string + self.send_response(self.iopub_socket, 'execute_result', { + 'data': {"text/plain": ""}, + 'metadata': {'quarto': {'daemonize': False}}, + 'execution_count': self.shell.execution_count, + }) + code_cell = Cell(self, code, silent) try: code_cell.run() diff --git a/nbstata/quarto_setup_cell b/nbstata/quarto_setup_cell new file mode 100644 index 0000000..9a85508 --- /dev/null +++ b/nbstata/quarto_setup_cell @@ -0,0 +1 @@ +56ed7992-3715-4d16-a6c0-e5f98c12799d \ No newline at end of file diff --git a/nbstata/stata.py b/nbstata/stata.py index 1c8a677..1b45f1e 100644 --- a/nbstata/stata.py +++ b/nbstata/stata.py @@ -3,8 +3,8 @@ # AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_stata.ipynb. # %% auto 0 -__all__ = ['get_local', 'set_local', 'get_global', 'get_scalar', 'stata_formatted', 'variable_names', 'drop_var', 'obs_count', - 'pwd', 'macro_expand', 'run_direct', 'run_single'] +__all__ = ['get_local', 'set_local', 'get_global', 'set_global', 'get_scalar', 'stata_formatted', 'variable_names', 'drop_var', + 'obs_count', 'pwd', 'macro_expand', 'run_direct', 'run_single'] # %% ../nbs/02_stata.ipynb 5 from .misc_utils import print_red @@ -27,47 +27,52 @@ def get_global(name): return sfi.Macro.getGlobal(name) # %% ../nbs/02_stata.ipynb 15 +def set_global(name): + import sfi + return sfi.Macro.setGlobal(name, value) + +# %% ../nbs/02_stata.ipynb 17 def get_scalar(name): import sfi return sfi.Scalar.getValue(name) -# %% ../nbs/02_stata.ipynb 17 +# %% ../nbs/02_stata.ipynb 19 def stata_formatted(value, s_format): import sfi return sfi.SFIToolkit.formatValue(value, s_format) -# %% ../nbs/02_stata.ipynb 19 +# %% ../nbs/02_stata.ipynb 21 def variable_names(): from sfi import Data return [Data.getVarName(i) for i in range(Data.getVarCount())] -# %% ../nbs/02_stata.ipynb 23 +# %% ../nbs/02_stata.ipynb 25 def drop_var(name): import sfi sfi.Data.dropVar(name) -# %% ../nbs/02_stata.ipynb 26 +# %% ../nbs/02_stata.ipynb 28 def obs_count(): """Count the number of observations""" import sfi return sfi.Data.getObsTotal() -# %% ../nbs/02_stata.ipynb 29 +# %% ../nbs/02_stata.ipynb 31 def pwd(): from sfi import SFIToolkit return SFIToolkit.getWorkingDir() -# %% ../nbs/02_stata.ipynb 32 +# %% ../nbs/02_stata.ipynb 34 def macro_expand(s): from sfi import SFIToolkit return SFIToolkit.macroExpand(s) -# %% ../nbs/02_stata.ipynb 35 +# %% ../nbs/02_stata.ipynb 37 def run_direct(cmds, quietly=False, echo=False, inline=True): import pystata return pystata.stata.run(cmds, quietly, echo, inline) -# %% ../nbs/02_stata.ipynb 43 +# %% ../nbs/02_stata.ipynb 45 def run_single(cmd, echo=False): import sfi try: