Skip to content

Html show doc rendering #1460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -33,3 +33,4 @@ jobs:
ls -la _docs
exit 1
fi

1 change: 1 addition & 0 deletions nbdev/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand Down
34 changes: 29 additions & 5 deletions nbdev/showdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"<th>{unescape_cell(cell)}</th>" for cell in split_row(lines[0])]
rows = [[f"<td>{unescape_cell(cell)}</td>" for cell in split_row(line)] for line in lines[2:]]

return f'''<table>
<thead><tr>{' '.join(header)}</tr></thead>
<tbody>{''.join(f'<tr>{" ".join(row)}</tr>' for row in rows)}</tbody>
</table>'''

# %% ../nbs/api/08_showdoc.ipynb
def _html_link(url, txt): return f'<a href="{url}" target="_blank" rel="noreferrer noopener">{txt}</a>'

class BasicHtmlRenderer(ShowDocRenderer):
"Simple HTML renderer for `show_doc`"
"HTML renderer for `show_doc`"
def _repr_html_(self):
doc = '<hr/>\n'
src = NbdevLookup().code(self.fn)
if src:
doc += f'<div style="float:right; font-size:smaller">{_html_link(src, "source")}</div>\n'
doc += f'<h{self.title_level}>{self.nm}</h{self.title_level}>\n'
doc += f'<blockquote><pre><code>{self.nm}{_fmt_sig(self.sig)}</code></pre></blockquote>'
if self.docs: doc += f"<p><i>{self.docs}</i></p>"
sig = _fmt_sig(self.sig) if self.sig else ''
# Escape < and > characters in the signature
sig = sig.replace('<', '&lt;').replace('>', '&gt;')
doc += f'<blockquote><pre><code>{self.nm} {sig}</code></pre></blockquote>'
if self.docs:
doc += f"<p><i>{self.docs}</i></p>"
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<p>' +_html_link(docs, "Show in docs") + '</p>'
display(HTML(res))

# %% ../nbs/api/08_showdoc.ipynb
Expand Down
57 changes: 42 additions & 15 deletions nbs/api/08_showdoc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -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\"<th>{unescape_cell(cell)}</th>\" for cell in split_row(lines[0])]\n",
" rows = [[f\"<td>{unescape_cell(cell)}</td>\" for cell in split_row(line)] for line in lines[2:]]\n",
" \n",
" return f'''<table>\n",
" <thead><tr>{' '.join(header)}</tr></thead>\n",
" <tbody>{''.join(f'<tr>{\" \".join(row)}</tr>' for row in rows)}</tbody>\n",
" </table>'''"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -968,20 +993,27 @@
"def _html_link(url, txt): return f'<a href=\"{url}\" target=\"_blank\" rel=\"noreferrer noopener\">{txt}</a>'\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 = '<hr/>\\n'\n",
" src = NbdevLookup().code(self.fn)\n",
" if src:\n",
" doc += f'<div style=\"float:right; font-size:smaller\">{_html_link(src, \"source\")}</div>\\n'\n",
" doc += f'<h{self.title_level}>{self.nm}</h{self.title_level}>\\n'\n",
" doc += f'<blockquote><pre><code>{self.nm}{_fmt_sig(self.sig)}</code></pre></blockquote>'\n",
" if self.docs: doc += f\"<p><i>{self.docs}</i></p>\"\n",
" sig = _fmt_sig(self.sig) if self.sig else ''\n",
" # Escape < and > characters in the signature\n",
" sig = sig.replace('<', '&lt;').replace('>', '&gt;')\n",
" doc += f'<blockquote><pre><code>{self.nm} {sig}</code></pre></blockquote>'\n",
" if self.docs:\n",
" doc += f\"<p><i>{self.docs}</i></p>\"\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<p>' +_html_link(docs, \"Show in docs\") + '</p>'\n",
" display(HTML(res))"
]
},
Expand All @@ -1008,9 +1040,12 @@
"data": {
"text/html": [
"<hr/>\n",
"<div style=\"float:right; font-size:smaller\"><a href=\"https://github.com/fastai/nbdev/blob/master/nbdev/showdoc.py#L182\" target=\"_blank\" rel=\"noreferrer noopener\">source</a></div>\n",
"<h3>show_doc</h3>\n",
"<blockquote><pre><code>show_doc(sym, renderer=None, name:str|None=None, title_level:int=3)</code></pre></blockquote><p>Show signature and docstring for `sym`</p>\n",
"<p><a href=\"https://nbdev.fast.ai/api/showdoc.html#show_doc\" target=\"_blank\" rel=\"noreferrer noopener\">Show in docs</a></p>"
"<blockquote><pre><code>show_doc (sym, renderer=None, name:str|None=None, title_level:int=3)</code></pre></blockquote><p><i>Show signature and docstring for `sym`</i></p><table>\n",
" <thead><tr><th></th> <th>Type</th> <th>Default</th> <th>Details</th> <th></th></tr></thead>\n",
" <tbody><tr><td>sym</td> <td></td> <td></td> <td>Symbol to document</td> <td></td></tr><tr><td>renderer</td> <td>NoneType</td> <td>None</td> <td>Optional renderer (defaults to markdown)</td> <td></td></tr><tr><td>name</td> <td>str | None</td> <td>None</td> <td>Optionally override displayed name of `sym`</td> <td></td></tr><tr><td>title_level</td> <td>int</td> <td>3</td> <td>Heading level to use for symbol name</td> <td></td></tr></tbody>\n",
" </table>"
],
"text/plain": [
"<IPython.core.display.HTML object>"
Expand Down Expand Up @@ -1341,14 +1376,6 @@
"#|hide\n",
"import nbdev; nbdev. nbdev_export()"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "d478691b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
105 changes: 32 additions & 73 deletions nbs/tutorials/tutorial.ipynb.off → nbs/tutorials/tutorial.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
},
{
Expand Down Expand Up @@ -864,7 +864,7 @@
"\n",
"> say_hello (to)\n",
"\n",
"Say hello to somebody\n",
"*Say hello to somebody*\n",
"\n",
":::\n",
"\n",
Expand Down Expand Up @@ -988,28 +988,6 @@
"from IPython.display import display,SVG"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"100\"><circle cx=\"50\" cy=\"50\" r=\"40\"/></svg>"
],
"text/plain": [
"<IPython.core.display.SVG object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"display(SVG('<svg height=\"100\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"50\" cy=\"50\" r=\"40\"/></svg>'))"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -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": [
Expand All @@ -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))"
]
},
{
Expand All @@ -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": {},
Expand Down
Loading