> ## Documentation Index
> Fetch the complete documentation index at: https://phiki.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CommonMark

> Learn how to use Phiki with The PHP League's CommonMark library.

If you're using `league/commonmark` to parse and render Markdown in your PHP project, you can easily integrate Phiki using our custom extension.

## Usage

```php theme={null}
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\MarkdownConverter;
use Phiki\Adapters\CommonMark\PhikiExtension;
use Phiki\Theme\Theme;

$environment = new Environment;
$environment
    ->addExtension(new CommonMarkCoreExtension)
    ->addExtension(new PhikiExtension(Theme::GithubLight));

$converter = new MarkdownConverter($environment);
$output = $converter->convert("My awesome blog post with code blocks...");
```

### Enabling the gutter

You can enable the gutter by specifying the `withGutter` argument in the `PhikiExtension` constructor.

```php theme={null}
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\MarkdownConverter;
use Phiki\Adapters\CommonMark\PhikiExtension;
use Phiki\Theme\Theme;

$environment = new Environment;
$environment
    ->addExtension(new CommonMarkCoreExtension)
    ->addExtension(new PhikiExtension(Theme::GithubLight, withGutter: true)); // [!code ++]
```

### Using multiple themes

You can also pass in an array of themes to the `PhikiExtension` constructor.

```php theme={null}
use League\CommonMark\Environment\Environment;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\MarkdownConverter;
use Phiki\Adapters\CommonMark\PhikiExtension;
use Phiki\Theme\Theme;

$environment = new Environment;
$environment
    ->addExtension(new CommonMarkCoreExtension)
    ->addExtension(new PhikiExtension([ // [!code ++]
        'light' => Theme::GithubLight, // [!code ++]
        'dark' => Theme::GithubDark, // [!code ++]
    ])); // [!code ++]
```

### Meta information

You can add additional meta information to your Markdown code blocks to highlight and focus a specified set of lines.

#### Highlighting lines

You can highlight lines in your code blocks using special annotations in the code block's info string.

````md theme={null}
```php {2,4-8}
````

The braces represent the lines to highlight. In this example, line 2 will be highlighted, as well as lines 4 through 8.

#### Focusing lines

You can focus lines in your code blocks using special annotations in the code block's info string.

````md theme={null}
```php {}{2,4-8}
````

The first set of braces represents the lines to highlight (none in this case), while the second set of braces represents the lines to focus. In this example, line 2 will be focused, as well as lines 4 through 8.

<Tip>
  When you have focused lines inside of a code block, Phiki will add a `focus` class to the `<pre>` element.
</Tip>

#### Sample CSS

Phiki does not style the highlighted or focused lines by default, so you will need to add your own CSS.

You can use the following sample CSS to get started:

```css theme={null}
pre.phiki code .line.highlight {
    background-color: hsl(197, 88%, 94%);
}

pre.phiki.focus .line:not(.focus) {
    transition: all 250ms;
    filter: blur(2px);
}

pre.phiki.focus:hover .line {
    transition: all 250ms;
    filter: blur(0);
}
```

### Inline annotations

The meta information for highlighting and focusing lines can be difficult to use when you have a large code block or if you change the code frequently since it uses line numbers.

That's why Phiki also supports inline annotations using special comments in your code.

#### Ranges

Inline annotations accept an optional range parameter to specify which lines should be highlighted or focused.

```
// [code! highlight]      → Only this line.
// [code! highlight:2]    → This line and the 2 lines after it.
// [code! highlight:-2]   → This line and the 2 lines before it.
// [code! highlight:1,3]  → From the next line, 3 lines in total.
// [code! highlight:-1,2] → From the previous line, 2 lines in total.
```

It's also possible to create an "open ended" range by using `start` and `end` to mark the beginning and end of a range.

```
// [code! highlight:start] → Start highlighting from this line.
// ...
// [code! highlight:end]   → Stop highlighting after this line.
```

#### Highlighting lines

To highlight a line, you can add a trailing comment to the line you want to highlight.

```php theme={null}
echo "Hello, world!"; // [code! highlight]
```

This comment tells Phiki to highlight this line by adding a `highlight` class to the corresponding line element.

If you don't want to write out `highlight` every time, you can use the `hl` or `~~` shorthands instead.

```php theme={null}
echo "Hello, world!"; // [code! hl]
echo "Hello, world!"; // [code! ~~]
```

#### Focusing lines

To focus a line, you can add a trailing comment to the line you want to focus.

```php theme={null}
echo "Hello, world!"; // [code! focus]
```

This comment tells Phiki to focus this line by adding a `focus` class to the corresponding line element.

<Tip>
  When you have focused lines inside of a code block, Phiki will add a `focus` class to the `<pre>` element.
</Tip>

If you don't want to write out `focus` every time, you can use the `f` or `**` shorthands instead.

```php theme={null}
echo "Hello, world!"; // [code! f]
echo "Hello, world!"; // [code! **]
```

#### Diff annotations

Diff annotations are useful for displaying changes in a piece of code, e.g. inserting a line or removing a line.

```php theme={null}
$user = User::find(1); // [code! remove]
$user = User::findOrFail(1); // [code! insert]
```

This will add `insert` and `remove` classes to the corresponding line elements.

If you don't want to write out the full keywords, you can use these shorthands:

```php theme={null}
$user = User::find(1); // [code! --]
$user = User::findOrFail(1); // [code! ++]
```

You can also use `add`, `del`, or `delete` as alternative keywords for insert and remove respectively.

##### **Gutter diff symbols**

When the gutter is enabled, line numbers will be replaced with the following symbols based on which type of diff annotation is used:

* Inserted lines show `+` instead of the line number.
* Removed lines show `-` instead of the line number

```php theme={null}
$environment = new Environment;
$environment
    ->addExtension(new CommonMarkCoreExtension)
    ->addExtension(new PhikiExtension(Theme::GithubLight, withGutter: true));
```

#### Sample CSS

##### **Highlighted lines**

When you use an inline highlight annotation, Phiki will automatically try to find an `editor.lineHighlightBackground` or `editor.selectionHighlightBackground` color inside of your chosen theme(s) and add a CSS variable to the `<pre>` element.

If it can't find one, it will fallback to the default background color of the theme.

Phiki automatically adds the following CSS variables:

* `--phiki-line-highlight` - Background color for highlighted lines

Those CSS variables are then applied to the line element the same as other styled elements.

<Note>
  If you're using multiple themes, Phiki will also add CSS variables for each theme so you can style them differently in dark mode, for example.
</Note>

```css theme={null}
@media (prefers-color-scheme: dark) {
    .phiki .line.highlight {
        background-color: var(--phiki-dark-line-highlight) !important;
    }
}
```

##### **Focused lines**

Phiki does not apply any styles to focused lines by default, so you will need to add your own CSS.

```css theme={null}
pre.phiki.focus .line:not(.focus) {
    transition: all 250ms;
    filter: blur(2px);
}

pre.phiki.focus:hover .line {
    transition: all 250ms;
    filter: blur(0);
}
```

##### **Diff annotations**

When you use diff annotations, Phiki will automatically try to find `markup.inserted` and `markup.deleted` colors inside of your chosen theme(s) and add CSS variables to the `<pre>` element.

Phiki automatically adds the following CSS variables to the `<pre>` element:

* `--phiki-diff-insert-bg` - Background color for inserted lines
* `--phiki-diff-insert-fg` - Text color for inserted lines
* `--phiki-diff-remove-bg` - Background color for removed lines
* `--phiki-diff-remove-fg` - Text color for removed lines

You can use these variables in your CSS:

```css theme={null}
.phiki .line.insert {
    background-color: var(--phiki-diff-insert-bg);
    color: var(--phiki-diff-insert-fg);
}

.phiki .line.remove {
    background-color: var(--phiki-diff-remove-bg);
    color: var(--phiki-diff-remove-fg);
}
```

<Note>
  If you're using multiple themes, Phiki will also add CSS variables for each theme so you can style them differently in dark mode, for example.
</Note>

```css theme={null}
@media (prefers-color-scheme: dark) {
    .phiki .line.insert {
        background-color: var(--phiki-dark-diff-insert-bg) !important;
        color: var(--phiki-dark-diff-insert-fg) !important;
    }

    .phiki .line.remove {
        background-color: var(--phiki-dark-diff-remove-bg) !important;
        color: var(--phiki-dark-diff-remove-fg) !important;
    }
}
```
