diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 139699462..229ef9977 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -22,7 +22,7 @@ jobs: if: ${{ (github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch') && matrix.version == '3.10' && matrix.os == 'ubuntu' }} run: | set -ux - wget -q $(curl https://latest.fast.ai/pre/quarto-dev/quarto-cli/linux-amd64.deb) + wget -q $(curl https://latest.fast.ai/latest/quarto-dev/quarto-cli/linux-amd64.deb) sudo dpkg -i quarto*.deb nbdev_docs if [ -f "_docs/index.html" ]; then @@ -33,3 +33,4 @@ jobs: ls -la _docs exit 1 fi + diff --git a/nbdev/_modidx.py b/nbdev/_modidx.py index 07d4d0676..f7001f253 100644 --- a/nbdev/_modidx.py +++ b/nbdev/_modidx.py @@ -334,6 +334,7 @@ 'nbdev.showdoc.ShowDocRenderer': ('api/showdoc.html#showdocrenderer', 'nbdev/showdoc.py'), 'nbdev.showdoc.ShowDocRenderer.__init__': ('api/showdoc.html#showdocrenderer.__init__', 'nbdev/showdoc.py'), 'nbdev.showdoc._bold': ('api/showdoc.html#_bold', 'nbdev/showdoc.py'), + 'nbdev.showdoc._create_html_table': ('api/showdoc.html#_create_html_table', 'nbdev/showdoc.py'), 'nbdev.showdoc._docstring': ('api/showdoc.html#_docstring', 'nbdev/showdoc.py'), 'nbdev.showdoc._escape_markdown': ('api/showdoc.html#_escape_markdown', 'nbdev/showdoc.py'), 'nbdev.showdoc._ext_link': ('api/showdoc.html#_ext_link', 'nbdev/showdoc.py'), diff --git a/nbdev/showdoc.py b/nbdev/showdoc.py index 00faeb43b..75a86cbb4 100644 --- a/nbdev/showdoc.py +++ b/nbdev/showdoc.py @@ -192,24 +192,48 @@ def show_doc(sym, # Symbol to document if isinstance(sym, TypeDispatch): pass else:return renderer(sym or show_doc, name=name, title_level=title_level) +# %% ../nbs/api/08_showdoc.ipynb +def _create_html_table(table_str): + def split_row(row): + return re.findall(r'\|(?:(?:\\.|[^|\\])*)', row) + + def unescape_cell(cell): + return cell.strip(' *|').replace(r'\|', '|') + + lines = table_str.strip().split('\n') + header = [f"{unescape_cell(cell)}" for cell in split_row(lines[0])] + rows = [[f"{unescape_cell(cell)}" for cell in split_row(line)] for line in lines[2:]] + + return f''' + {' '.join(header)} + {''.join(f'{" ".join(row)}' for row in rows)} +
''' + # %% ../nbs/api/08_showdoc.ipynb def _html_link(url, txt): return f'{txt}' class BasicHtmlRenderer(ShowDocRenderer): - "Simple HTML renderer for `show_doc`" + "HTML renderer for `show_doc`" def _repr_html_(self): doc = '
\n' + src = NbdevLookup().code(self.fn) + if src: + doc += f'
{_html_link(src, "source")}
\n' doc += f'{self.nm}\n' - doc += f'
{self.nm}{_fmt_sig(self.sig)}
' - if self.docs: doc += f"

{self.docs}

" + sig = _fmt_sig(self.sig) if self.sig else '' + # Escape < and > characters in the signature + sig = sig.replace('<', '<').replace('>', '>') + doc += f'
{self.nm} {sig}
' + if self.docs: + doc += f"

{self.docs}

" + if self.dm.has_docment: + doc += _create_html_table(str(self.dm)) return doc def doc(self): "Show `show_doc` info along with link to docs" from IPython.display import display,HTML res = self._repr_html_() - docs = NbdevLookup().doc(self.fn) - if docs is not None: res += '\n

' +_html_link(docs, "Show in docs") + '

' display(HTML(res)) # %% ../nbs/api/08_showdoc.ipynb diff --git a/nbs/api/08_showdoc.ipynb b/nbs/api/08_showdoc.ipynb index 76452eea0..4fbbd7e2a 100644 --- a/nbs/api/08_showdoc.ipynb +++ b/nbs/api/08_showdoc.ipynb @@ -957,6 +957,31 @@ "You can replace the default markdown show_doc renderer with custom renderers. For instance, nbdev comes with a simple example for rendering with raw HTML." ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "9a6c4f96", + "metadata": {}, + "outputs": [], + "source": [ + "#| export\n", + "def _create_html_table(table_str):\n", + " def split_row(row):\n", + " return re.findall(r'\\|(?:(?:\\\\.|[^|\\\\])*)', row)\n", + " \n", + " def unescape_cell(cell): \n", + " return cell.strip(' *|').replace(r'\\|', '|')\n", + " \n", + " lines = table_str.strip().split('\\n')\n", + " header = [f\"{unescape_cell(cell)}\" for cell in split_row(lines[0])]\n", + " rows = [[f\"{unescape_cell(cell)}\" for cell in split_row(line)] for line in lines[2:]]\n", + " \n", + " return f'''\n", + " {' '.join(header)}\n", + " {''.join(f'{\" \".join(row)}' for row in rows)}\n", + "
'''" + ] + }, { "cell_type": "code", "execution_count": null, @@ -968,20 +993,27 @@ "def _html_link(url, txt): return f'{txt}'\n", "\n", "class BasicHtmlRenderer(ShowDocRenderer):\n", - " \"Simple HTML renderer for `show_doc`\"\n", + " \"HTML renderer for `show_doc`\"\n", " def _repr_html_(self):\n", " doc = '
\\n'\n", + " src = NbdevLookup().code(self.fn)\n", + " if src:\n", + " doc += f'
{_html_link(src, \"source\")}
\\n'\n", " doc += f'{self.nm}\\n'\n", - " doc += f'
{self.nm}{_fmt_sig(self.sig)}
'\n", - " if self.docs: doc += f\"

{self.docs}

\"\n", + " sig = _fmt_sig(self.sig) if self.sig else ''\n", + " # Escape < and > characters in the signature\n", + " sig = sig.replace('<', '<').replace('>', '>')\n", + " doc += f'
{self.nm} {sig}
'\n", + " if self.docs:\n", + " doc += f\"

{self.docs}

\"\n", + " if self.dm.has_docment:\n", + " doc += _create_html_table(str(self.dm))\n", " return doc\n", "\n", " def doc(self):\n", " \"Show `show_doc` info along with link to docs\"\n", " from IPython.display import display,HTML\n", " res = self._repr_html_()\n", - " docs = NbdevLookup().doc(self.fn)\n", - " if docs is not None: res += '\\n

' +_html_link(docs, \"Show in docs\") + '

'\n", " display(HTML(res))" ] }, @@ -1008,9 +1040,12 @@ "data": { "text/html": [ "
\n", + "
source
\n", "

show_doc

\n", - "
show_doc(sym, renderer=None, name:str|None=None, title_level:int=3)

Show signature and docstring for `sym`

\n", - "

Show in docs

" + "
show_doc (sym, renderer=None, name:str|None=None, title_level:int=3)

Show signature and docstring for `sym`

\n", + " \n", + " \n", + "
Type Default Details
sym Symbol to document
renderer NoneType None Optional renderer (defaults to markdown)
name str | None None Optionally override displayed name of `sym`
title_level int 3 Heading level to use for symbol name
" ], "text/plain": [ "" @@ -1341,14 +1376,6 @@ "#|hide\n", "import nbdev; nbdev. nbdev_export()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d478691b", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { diff --git a/nbs/tutorials/tutorial.ipynb.off b/nbs/tutorials/tutorial.ipynb similarity index 96% rename from nbs/tutorials/tutorial.ipynb.off rename to nbs/tutorials/tutorial.ipynb index 24a77cd1f..ceff5b874 100644 --- a/nbs/tutorials/tutorial.ipynb.off +++ b/nbs/tutorials/tutorial.ipynb @@ -7,9 +7,9 @@ "# End-To-End Walkthrough\n", "\n", "> A step-by-step guide to using nbdev\n", + "\n", "- order: 1\n", - "- image: ../images/card.png\n", - "- aliases: [/tutorial.html]" + "- image: ../images/card.png" ] }, { @@ -864,7 +864,7 @@ "\n", "> say_hello (to)\n", "\n", - "Say hello to somebody\n", + "*Say hello to somebody*\n", "\n", ":::\n", "\n", @@ -988,28 +988,6 @@ "from IPython.display import display,SVG" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "display(SVG(''))" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -1140,29 +1118,48 @@ "text/markdown": [ "---\n", "\n", - "[source](https://github.com/fastai/nbdevblob/master/nbdev/tutorial.py#L12){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", "### HelloSayer\n", "\n", "> HelloSayer (to)\n", "\n", - "Say hello to `to` using `say_hello`" + "*Say hello to `to` using `say_hello`*" ], "text/plain": [ "---\n", "\n", - "[source](https://github.com/fastai/nbdevblob/master/nbdev/tutorial.py#L12){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", "### HelloSayer\n", "\n", "> HelloSayer (to)\n", "\n", - "Say hello to `to` using `say_hello`" + "*Say hello to `to` using `say_hello`*" ] }, - "execution_count": null, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" + }, + { + "data": { + "text/markdown": [ + "---\n", + "\n", + "### HelloSayer.say\n", + "\n", + "> HelloSayer.say ()\n", + "\n", + "*Do the saying*" + ], + "text/plain": [ + "---\n", + "\n", + "### HelloSayer.say\n", + "\n", + "> HelloSayer.say ()\n", + "\n", + "*Do the saying*" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ @@ -1173,8 +1170,9 @@ " def say(self):\n", " \"Do the saying\"\n", " return say_hello(self.to)\n", + "display(show_doc(HelloSayer))\n", "\n", - "show_doc(HelloSayer)" + "display(show_doc(HelloSayer.say))" ] }, { @@ -1195,45 +1193,6 @@ "```" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [ - { - "data": { - "text/markdown": [ - "---\n", - "\n", - "[source](https://github.com/fastai/nbdevblob/master/nbdev/tutorial.py#LNone){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", - "### HelloSayer.say\n", - "\n", - "> HelloSayer.say ()\n", - "\n", - "Do the saying" - ], - "text/plain": [ - "---\n", - "\n", - "[source](https://github.com/fastai/nbdevblob/master/nbdev/tutorial.py#LNone){target=\"_blank\" style=\"float:right; font-size:smaller\"}\n", - "\n", - "### HelloSayer.say\n", - "\n", - "> HelloSayer.say ()\n", - "\n", - "Do the saying" - ] - }, - "execution_count": null, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "show_doc(HelloSayer.say)" - ] - }, { "cell_type": "markdown", "metadata": {},