Skip to content

Commit

Permalink
Merge pull request #1463 from Isaac-Flath/HTMLRendererImprovements
Browse files Browse the repository at this point in the history
Html renderer improvements
  • Loading branch information
jph00 authored Oct 20, 2024
2 parents dc110c9 + 16fc9bc commit b263f6b
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 15 deletions.
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
33 changes: 28 additions & 5 deletions nbdev/showdoc.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,47 @@ 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>'

# %% ../nbs/api/08_showdoc.ipynb
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)
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 src: doc += f"<br/>{_html_link(src, 'source')}"
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
61 changes: 51 additions & 10 deletions nbs/api/08_showdoc.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -957,31 +957,70 @@
"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": "5271cd9a",
"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,
"id": "a4ae5b2a",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def _html_link(url, txt): return f'<a href=\"{url}\" target=\"_blank\" rel=\"noreferrer noopener\">{txt}</a>'"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "147626ee",
"metadata": {},
"outputs": [],
"source": [
"#|export\n",
"def _html_link(url, txt): return f'<a href=\"{url}\" target=\"_blank\" rel=\"noreferrer noopener\">{txt}</a>'\n",
"\n",
"#| export\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",
" 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 src: doc += f\"<br/>{_html_link(src, 'source')}\"\n",
" if self.dm.has_docment: 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 Down Expand Up @@ -1009,8 +1048,10 @@
"text/html": [
"<hr/>\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><br/><a href=\"https://github.com/fastai/nbdev/blob/master/nbdev/showdoc.py#L182\" target=\"_blank\" rel=\"noreferrer noopener\">source</a><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

0 comments on commit b263f6b

Please sign in to comment.