# HTML Inline Formatter (/formatters/html-inline)

Self-contained HTML with inline styles on each token. No external CSS required.

## Options

| Runtime | Options |
| --- | --- |
| Rust | `language`, `structure`, `theme`, `pre_class`, `pre_attrs`, `code_attrs`, `include_highlights`, `highlight_lines`, `line_numbers`, `header` |
| Elixir | `language`, `structure`, `theme`, `pre_class`, `pre_attrs`, `code_attrs`, `include_highlights`, `highlight_lines`, `line_numbers`, `header` |
| JavaScript / TypeScript | `language`, `structure`, `theme`, `preClass`, `preAttrs`, `codeAttrs`, `includeHighlights`, `highlightLines`, `lineNumbers`, `header` |
| Java | `withLang()`, `withTheme()`, `withFormatter(Formatter.HTML_INLINE)` |
| CLI | `--structure`, `--theme`, `--pre-class`, `--pre-attr`, `--no-pre-attr`, `--code-attr`, `--no-code-attr`, `--include-highlights`, `--highlight-lines`, `--highlight-lines-class`, `--highlight-lines-style`, `--line-numbers`, `--header-open`, `--header-close` |

Use `pre_attrs` / `preAttrs` to set a custom block background or make it
transparent so an enclosing card shows through. See
[Override the block background](/formatters#override-the-block-background).

## Basic example

### JavaScript / TypeScript

```js
import {highlight} from '@lumis-sh/lumis'
import {htmlInline} from '@lumis-sh/lumis/formatters'
import rust from '@lumis-sh/wasm-rust'
import frappe from '@lumis-sh/themes/catppuccin_frappe'

const html = await highlight(
  'fn main() {}',
  htmlInline({language: rust, theme: frappe}),
)
```

### Rust

```rust
use lumis::{
    highlight, languages::Language, themes,
    HtmlInlineBuilder,
};

let html = highlight(
    "fn main() {}",
    HtmlInlineBuilder::new()
        .language(Language::Rust)
        .theme(Some(
            themes::get("catppuccin_frappe").unwrap(),
        ))
        .build()
        .unwrap(),
);
```

### Elixir

```elixir
Lumis.highlight!(
  "fn main() {}",
  formatter:
    {:html_inline,
     language: "rust", theme: "catppuccin_frappe"}
)
```

### Java

```java
import io.roastedroot.lumis4j.core.Formatter;
import io.roastedroot.lumis4j.core.Lang;
import io.roastedroot.lumis4j.core.Lumis;
import io.roastedroot.lumis4j.core.Theme;

var lumis = Lumis.builder().build();

var highlighter = lumis.highlighter()
    .withLang(Lang.RUST)
    .withTheme(Theme.CATPPUCCIN_FRAPPE)
    .withFormatter(Formatter.HTML_INLINE)
    .build();

var html = highlighter.highlight("fn main() {}").string();

lumis.close();
```

### CLI

```bash
lumis highlight main.rs \
  --formatter html-inline \
  --theme catppuccin_frappe
```


## Add classes and metadata

### JavaScript / TypeScript

```js
const html = await highlight(
  'const x = 1',
  htmlInline({
    language: javascript,
    theme: frappe,
    preClass: 'code-block',
    includeHighlights: true,
  })
)
```

### Rust

```rust
let formatter = HtmlInlineBuilder::new()
    .language(Language::JavaScript)
    .theme(Some(themes::get("catppuccin_frappe").unwrap()))
    .pre_class(Some("code-block".to_string()))
    .include_highlights(true)
    .build()
    .unwrap();

let html = highlight("const x = 1", formatter);
```

### Elixir

```elixir
Lumis.highlight!(
  "const x = 1",
  formatter:
    {:html_inline,
     language: "javascript",
     theme: "catppuccin_frappe",
     pre_class: "code-block",
     include_highlights: true}
)
```

### Java

`lumis4j` does not currently expose `preClass` or `includeHighlights` for HTML Inline output.

### CLI

```bash
lumis highlight app.js \
  -f html-inline -t catppuccin_frappe \
  --pre-class my-code \
  --include-highlights
```


## Wrap with custom HTML

### JavaScript / TypeScript

```js
const html = await highlight(
  'const x = 1',
  htmlInline({
    language: javascript,
    theme: frappe,
    header: {
      openTag: '<figure><figcaption>index.js</figcaption>',
      closeTag: '</figure>',
    },
  })
)
```

### Rust

```rust
use lumis::formatters::html::HtmlElement;

let formatter = HtmlInlineBuilder::new()
    .language(Language::JavaScript)
    .theme(Some(themes::get("catppuccin_frappe").unwrap()))
    .header(Some(HtmlElement {
        open_tag:
            "<figure><figcaption>index.js</figcaption>"
                .to_string(),
        close_tag: "</figure>".to_string(),
    }))
    .build()
    .unwrap();

let html = highlight("const x = 1", formatter);
```

### Elixir

```elixir
Lumis.highlight!(
  "const x = 1",
  formatter:
    {:html_inline,
     language: "javascript",
     theme: "catppuccin_frappe",
     header: %{
       open_tag:
         "<figure><figcaption>index.js</figcaption>",
       close_tag: "</figure>"
     }}
)
```

### Java

Custom HTML wrappers are not currently exposed by `lumis4j`.

### CLI

```bash
lumis highlight app.js -f html-inline -t catppuccin_frappe \
  --header-open '<figure>' \
  --header-close '</figure>'
```

The two go together; clap rejects one without the other.


## Output format

HTML Inline emits the full block structure with inline styles on each token:

```html
<pre class="lumis" style="background-color: #303446; color: #c6d0f5;"><code class="language-rust" translate="no" tabindex="0"><span class="l-line" data-line="1"><span style="color: #ca9ee6;">fn</span> <span style="color: #8caaee;">main</span></span></code></pre>
```

- `<pre class="lumis">` is the outer wrapper and carries the block background
- `<code class="language-*">` identifies the language and keeps the block focusable
- `<span class="l-line" data-line="N">` wraps only a line's content
- `<span class="l-line-number">` opens the line when `line_numbers` is on, see [Line Numbers](/recipes/line-numbers)
- Lines are separated by `\n` text nodes; nothing follows the last line element
- A final source newline ends its line rather than adding an empty numbered line
- `<span style="...">` carries the token colors and font styles inline

With `structure: "inline"` only the token spans are written, for a `<code>` or
other element of your own. See [Inline code](/formatters#inline-code).

Highlighted lines and empty lines carry inline layout styles to preserve their
width and height. When `highlight_lines` is set, `<code>` expands to the scroll
width, so backgrounds cover long lines too. Line numbers are excluded from
selection copy. See [Line layout](/themes/css-files#line-layout) if you supply
custom CSS, and [Custom formatters](/formatters/custom) for line helpers.

For CSS or formatters written for line divs, see
[HTML line markup migration](/migrate/html-lines).

## When to use it

- self-contained HTML
- email / CMS / markdown export
- no external stylesheet pipeline