# hl


<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->

## Code

`hl_text(code, lang, theme)` colours a piece of code for the terminal.
`theme` is a Lumis theme name, and `HL_THEMES` gives the Lumis theme for
each palette name the terminal accepts, so `--theme nord` colours code
with `nord`.
[`scope_style`](https://vedicreader.github.io/ramabana/hl.html#scope_style)
looks up the style a theme gives one scope. A scope the theme does not
name uses its longest dotted prefix that it does name, so
`function.builtin` falls back to `function`.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/cli.py#L706"
target="_blank" style="float:right; font-size:smaller">source</a>

### hl_text

``` python
def hl_text(
    code, lang, theme:str='github_dark'
):
```

*`code` as a rich `Text`, coloured by fastpylight with Lumis `theme`.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L29"
target="_blank" style="float:right; font-size:smaller">source</a>

### scope_style

``` python
def scope_style(
    scope, theme:str='github_dark'
):
```

*The rich style Lumis `theme` gives token `scope`; the longest dotted
prefix it names wins.*

fastpylight counts positions in UTF-8 bytes and rich counts characters,
and [`hl_text`](https://vedicreader.github.io/ramabana/cli.html#hl_text)
converts between them, so each coloured span starts on the character its
token starts on. A line ending that rich rewrites, such as `\r\n`,
leaves the spans in place:

``` python
t = hl_text('a\r\nb = 1  # one', 'python')
test_eq(t.plain, 'a\nb = 1  # one')
assert any(t.plain[s.start:s.end] == '1' for s in t.spans)
t
```

`hl_toks(code, lang)` returns the tokens as data instead: one list per
line, each token a `(start, end, scope)` tuple in characters. Use it
when you draw the code yourself. A token that runs across a line break,
such as a triple-quoted string, is cut at the break and appears on both
lines:

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L47"
target="_blank" style="float:right; font-size:smaller">source</a>

### hl_toks

``` python
def hl_toks(
    code, lang
):
```

*Per line of `code`, its tokens as `(start, end, scope)` in characters;
a token crossing a line break is cut at it.*

``` python
t = hl_toks('é = """a\nb"""', 'python')
test_eq(t[0][0], (0, 1, 'variable'))
test_eq([k for *_, k in t[1]], ['string'])
```

## Diffs

`diff_rich(s, palette, theme)` colours a unified diff for the terminal.
It also colours a diffstat, the `file | 3 ++-` summary git prints, and
returns any other text in gray. `palette` maps `fg1`, `gray`, `red`,
`green`, `aqua` and `bg0` to colours. File headers are bold, hunk
headers are `aqua`, and added and removed lines get a background tinted
15% toward green or red. The code inside each hunk is coloured with
`theme` in its own language. The old side and the new side of a hunk are
each tokenized whole, so a string that spans several lines keeps its
colour on every one.
[`is_diff`](https://vedicreader.github.io/ramabana/hl.html#is_diff) says
whether a text holds a unified diff at all.

The same split is available as data.
[`diff_toks`](https://vedicreader.github.io/ramabana/hl.html#diff_toks)
returns one entry per line of a diff: the line’s tokens, or `None` for a
line outside a hunk body, such as a header.
[`hunk_toks`](https://vedicreader.github.io/ramabana/hl.html#hunk_toks)
does the same for one hunk body.
[`diff_html`](https://vedicreader.github.io/ramabana/hl.html#diff_html)
renders each code line as HTML through
[`toks_html`](https://vedicreader.github.io/ramabana/hl.html#toks_html),
which wraps each token in a span whose classes are its scope and every
prefix of it, as in `hl-function hl-function-builtin`, so a stylesheet
that styles only `function` still colours it.

[`diff_lang`](https://vedicreader.github.io/ramabana/hl.html#diff_lang)
picks the language of a hunk from the path on its `---` or `+++` line. A
notebook’s diff holds the source of its cells, so a path ending in
`.ipynb` reads as Python. So does a single cell, written `nb.ipynb#id`
the way `edit_cell` writes it. Any other path takes fastpylight’s guess
from the file name. The cells below check
[`diff_lang`](https://vedicreader.github.io/ramabana/hl.html#diff_lang),
then
[`diff_html`](https://vedicreader.github.io/ramabana/hl.html#diff_html)
on a small diff.

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/cli.py#L710"
target="_blank" style="float:right; font-size:smaller">source</a>

### diff_rich

``` python
def diff_rich(
    s, palette, theme:str='github_dark'
):
```

*`s` coloured in `palette` when it holds a unified diff, its code by the
file’s language, or a diffstat; else gray.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L143"
target="_blank" style="float:right; font-size:smaller">source</a>

### diff_html

``` python
def diff_html(
    s, lang:NoneType=None
):
```

*Per line of unified diff `s`, the HTML of its code after the prefix, or
`None` outside a hunk body.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L133"
target="_blank" style="float:right; font-size:smaller">source</a>

### toks_html

``` python
def toks_html(
    code, toks
):
```

*`code` escaped, each token a span whose classes are its scope and every
dotted prefix of it, as `fastpylight.theme_css` names them.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L121"
target="_blank" style="float:right; font-size:smaller">source</a>

### diff_toks

``` python
def diff_toks(
    s, lang:NoneType=None
):
```

*Tokens per line of unified diff `s`, relative to the line after its
prefix; `None` for every line outside a hunk body. `lang` overrides the
`---`/`+++` paths.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L113"
target="_blank" style="float:right; font-size:smaller">source</a>

### diff_lang

``` python
def diff_lang(
    path
):
```

*fastpylight’s language for a diffed `path`; a notebook, or one cell of
it as `nb.ipynb#id`, is Python.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L109"
target="_blank" style="float:right; font-size:smaller">source</a>

### is_diff

``` python
def is_diff(
    s
):
```

*Whether `s` holds a unified diff: at least one hunk header.*

------------------------------------------------------------------------

<a
href="https://github.com/vedicreader/ramabana/blob/main/ramabana/hl.py#L72"
target="_blank" style="float:right; font-size:smaller">source</a>

### hunk_toks

``` python
def hunk_toks(
    ls, lang
):
```

*Tokens per hunk body line, relative to the line after its prefix; each
side is tokenized whole, so a string spanning lines keeps its scope.
`None` for a `\` line.*

``` python
test_eq([diff_lang(p) for p in ('a/x.py', 'b/nbs/05_cli.ipynb', 'b/nbs/05_cli.ipynb#2874a64d', 'a/README.md')],
        ['python', 'python', 'python', 'markdown'])
```

``` python
d = '--- a/x.py\n+++ b/x.py\n@@ -1,3 +1,4 @@\n import os\n-x = "a<b"\n+s = """one\n+two"""\n é = 1  # ü\n\\ No newline at end of file'
h = diff_html(d)
test_eq(len(h), len(d.split('\n')))
test_eq(h[:3] + h[-1:], [None] * 4)
assert '&lt;' in h[4] and 'hl-string' in h[6]
assert '# ü' in h[7] and h[7].startswith('<span class="hl-variable">é</span>')
test_eq(diff_html('@@ -1 +1 @@\n-a<\n+b', 'plaintext'), [None, 'a&lt;', 'b'])
test_eq(toks_html('len(x)', [(0, 3, 'function.builtin')]), '<span class="hl-function hl-function-builtin">len</span>(x)')
```

Here is a notebook cell’s diff, as `edit_cell` reports it, in the
default `github-dark` colours. The added line carries the colour of its
`+` mark, the green tint, and the code’s own colours:

``` python
dark = {'fg1': '#c9d1d9', 'gray': '#8b949e', 'red': '#ff7b72', 'green': '#3fb950', 'aqua': '#39c5cf', 'bg0': '#0a0c10'}
nb_diff = diff_rich('--- a/nbs/x.ipynb#c1\n+++ b/nbs/x.ipynb#c1\n@@ -1 +1 @@\n-x = 1\n+def f(): return 2', dark)
added = nb_diff.split('\n')[-1]
test_eq(added.plain, '+def f(): return 2')
assert len({str(s.style) for s in added.spans}) > 2
test_eq(diff_rich('3 passed', dark).spans, [])
nb_diff
```
