Skip to content

Commit

Permalink
feat: added option to add line numbers to code blocks
Browse files Browse the repository at this point in the history
As requested in redimp#176 code blocks can be configured to display
line numbers by adding a = to the specified language. e.g.

```python=
print("Hello Line Numbers!")
```
  • Loading branch information
redimp committed Jan 12, 2025
1 parent 62e8f0d commit aaa4ab1
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 9 deletions.
21 changes: 14 additions & 7 deletions otterwiki/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def wrap(self, source):
yield 0, '</pre></div>'


def pygments_render(code, lang):
def pygments_render(code, lang, linenumbers=False):
try:
lexer = get_lexer_by_name(lang, stripall=True)
except ClassNotFound:
Expand All @@ -71,8 +71,8 @@ def pygments_render(code, lang):
mistune.escape(code.strip()),
)
)
formatter = CodeHtmlFormatter(classprefix=".highlight ")
# formatter = html.HtmlFormatter(classprefix=".highlight ")
linenos = "table" if linenumbers else None
formatter = CodeHtmlFormatter(classprefix=".highlight ", linenos=linenos)
return highlight(code, lexer, formatter)


Expand Down Expand Up @@ -161,8 +161,9 @@ def clean_html(html: str) -> str:
break
try:
if any(
x in element.attrs.keys() for x in REMOVE_ATTRIBUTES
): # pyright: ignore
x in element.attrs.keys()
for x in REMOVE_ATTRIBUTES # pyright: ignore
):
_escape = True
break
except AttributeError:
Expand Down Expand Up @@ -209,7 +210,8 @@ def codespan(self, text):

def block_code(self, code, info=None):
prefix = ""
if not info:
linenumbers = False
if not info or not len(info):
return (
'\n'
+ _pre_copy_to_clipboard_tag()
Expand All @@ -218,6 +220,9 @@ def block_code(self, code, info=None):
if cursormagicword in info:
info = info.replace(cursormagicword, "")
prefix = cursormagicword
if info[-1] == "=":
info = info[:-1]
linenumbers = True
cursorline, code = hidemagicword(code)
if info == "math":
html = "".join(
Expand All @@ -232,7 +237,9 @@ def block_code(self, code, info=None):
html = '\n<pre class="mermaid">{}\n</pre>\n'.format(code.strip())
return html
else:
html = prefix + pygments_render(code, info)
html = prefix + pygments_render(
code, info, linenumbers=linenumbers
)
html = showmagicword(cursorline, html)
return prefix + html

Expand Down
31 changes: 31 additions & 0 deletions otterwiki/static/css/elements/page.css
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,34 @@
.page table > :last-child > tr:last-child > th {
border-bottom: 0;
}

/* highlighttable with linenumbers */

.highlight table.highlighttable {
width: 100%;
padding: 0;
margin: 0;
background-color: transparent;
}

.highlight table > tbody > tr > td.linenos {
padding: 0;
margin: 0;
width: 0;
border-right: 0;
background-color: transparent;
}

.highlight table > tbody > tr > td.linenos > div.linenodiv > pre {
background-color: rgba(0, 0, 0, 0.1);
margin-block-start: 0;
margin-block-end: 0;
border: 1px solid rgba(0,0,0,.05);
}

.page table > tbody > tr > td.code {
padding: 0;
border: 0;
margin: 0;
background-color: transparent;
}
25 changes: 23 additions & 2 deletions otterwiki/templates/snippets/syntax.html
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ <h4>{{ name }}</h4>
</div>
</div>


<div class="row">
<div class="col-md-6 col-sm-12 p-5">
<pre>```
Expand All @@ -205,12 +206,18 @@ <h4>{{ name }}</h4>
</div>
</div>


<div class="row">
To add syntax highlighting, specify a language next to the backticks before the fenced code block.
</div>

<div class="row">
<div class="col-md-6 col-sm-12 p-5">
<pre class="block-compact">```python
#!/usr/bin/env python
assert 1 + 1 == 2
print("Hello World!")```</pre>
print("Hello World!")
```</pre>
</div>
<div class="col-md-6 col-sm-12 p-5">
<div class="highlight"><pre class="block-compact"><span></span><span class=".highlight ch">#!/usr/bin/env python</span>
Expand All @@ -220,6 +227,21 @@ <h4>{{ name }}</h4>
</div>
</div>

<div class="row">
To enable line numbers in the code block, append an equal sign <code>=</code> to the language.
</div>
<div class="row">
<div class="col-md-6 col-sm-12 p-5">
<pre class="block-compact">```python=
print("Hello Line Numbers!")
```</pre>
</div>
<div class="col-md-6 col-sm-12">
<div class="highlight"><table class="highlighttable"><tbody><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span></pre></div></td><td class="code"><div><div class="copy-to-clipboard-outer"><div class="copy-to-clipboard-inner"><button class="btn alt-dm btn-xsm copy-to-clipboard" onclick="otterwiki.copy_to_clipboard(this);" type="button"><i "="" alt="Copy to clipboard" aria-hidden="true" class="fa fa-copy"></i></button></div><pre class="copy-to-clipboard code"><span class=".highlight nb">print</span><span class=".highlight p">(</span><span class=".highlight s2">"Hello Line Numbers!"</span><span class=".highlight p">)</span>
</pre></div></div></td></tr></tbody></table></div>
</div>
</div>

{{ heading("Mathjax") }}

<div class="row">
Expand Down Expand Up @@ -406,4 +428,3 @@ <h4>Alerts</h4>
<a href="http://daringfireball.net/projects/markdown/syntax">syntax</a> for more information.

Please Note: An Otter Wiki is not using the official implementation. This might lead to small differences in the little things.

19 changes: 19 additions & 0 deletions tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ def test_code():
)
assert pre_code is not None
assert pre_code.text.startswith('non_existing_lexer')
# test highlight with line numbers
html, _ = render.markdown(
"""```python=
n = 2
```"""
)
assert '<table class="highlighttable">' in html
table_code = BeautifulSoup(html, "html.parser").find(
'table', attrs={"class": "highlighttable"}
)
assert table_code is not None
td_linenos = table_code.find(
"td", attrs={"class": "linenos"}
) # pyright: ignore
assert td_linenos is not None
assert td_linenos.text.startswith('1')
td_code = table_code.find("td", attrs={"class": "code"}) # pyright: ignore
assert td_code is not None
assert td_code.text.startswith('n = 2')


def test_img():
Expand Down

0 comments on commit aaa4ab1

Please sign in to comment.