Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Line numbers #3

Closed
jbrooksuk opened this issue Jan 4, 2019 · 17 comments
Closed

Line numbers #3

jbrooksuk opened this issue Jan 4, 2019 · 17 comments

Comments

@jbrooksuk
Copy link

Would it be possible to add support for line numbers?

Bonus points for not restricting you to auto-generate them either. For example, when showing a Git diff, the line numbers will change.

@octref
Copy link
Collaborator

octref commented Jan 4, 2019

It's possible, just need to add that to the HTML renderer.

You can do it too if you have time:

const shiki = require('shiki')

shiki.getHighlighter({
  theme: 'nord'
}).then(highlighter => {
  const tokens = highlighter.codeToThemedTokens(`console.log('shiki');`, 'js')
  const html = shiki.renderToHtml(tokens) // default renderer, replace with yours
})

@alexpeattie
Copy link
Contributor

As an alternative to writing a custom renderToHtml function: since v0.2.3 each line is wrapped in a <span class='line'> which makes it quite easy to do line numbering using CSS counters. I added some CSS like this:

code {
  counter-reset: step;
  counter-increment: step 0;
}

code .line::before {
  content: counter(step);
  counter-increment: step;
  width: 1rem;
  margin-right: 1.5rem;
  display: inline-block;
  text-align: right;
  color: rgba(115,138,148,.4)
}

Which yields:
Capture d’écran 2021-05-01 à 08 35 14

@bramus
Copy link

bramus commented Jul 16, 2021

Building further upon @alexpeattie's code: using Custom Properties you can set a different start number.

code {
	counter-reset: step;
	counter-increment: step calc(var(--start, 1) - 1);
}
<code style="--start: 13;"></code>

If no --start is set, it will fall back to start numbering at 1.

Demo: https://codepen.io/bramus/pen/mdmmdQB

(You might want to opt for a more unique name for the Custom Property)

@lloydjatkinson
Copy link

Given that line numbers is pretty much a normal expectation of syntax highlighting and that this issue has been open for three and a half years now, could one of the above solutions be built in?

@heychazza
Copy link

Given that line numbers is pretty much a normal expectation of syntax highlighting and that this issue has been open for three and a half years now, could one of the above solutions be built in?

I'd also love to see code diff highlighting, so for example showing added and removed lines of code (with highlighting for whatever lang).

@ghost
Copy link

ghost commented Nov 22, 2022

prefer the style of shiki, but compared with other similar plugins, such as Prism and highlight, they all have the line number function, hope shiki can also support it

@antfu
Copy link
Member

antfu commented Jan 26, 2024

Consider the solution #3 (comment) is quite solid and working well with the existing ecosystem, I think we could consider this is resolved. Otherwise, the newly introduced transformers API should allow this to be implemented on user land.

@tisonkun
Copy link

tisonkun commented Apr 2, 2024

#3 (comment) looks good. While with astro, I found there is always a trailing <span class='line' /> rendered and it cause an extra dangling line number.

Not sure if it's an issue of Shiki or astro.

In index.mdx file -

```rust
let x = 42;
Ok(x)
```

Rendered:

<pre class="astro-code github-light" style="background-color:#fff;color:#24292e;overflow-x:auto" tabindex="0"><code><span class="line"><span style="color:#D73A49">let</span><span style="color:#24292E"> x </span><span style="color:#D73A49">=</span><span style="color:#005CC5"> 42</span><span style="color:#24292E">;</span></span>
<span class="line"><span style="color:#6F42C1">Ok</span><span style="color:#24292E">(x)</span></span>
<span class="line"></span></code></pre>

Result:

image

@seancheung
Copy link

#3 (comment) looks good. While with astro, I found there is always a trailing <span class='line' /> rendered and it cause an extra dangling line number.

Not sure if it's an issue of Shiki or astro.

In index.mdx file -

```rust
let x = 42;
Ok(x)

Rendered:

let x = 42;
Ok(x)

Result:

<img alt="image" width="933" src="https://private-user-images.githubusercontent.com/18818196/318681030-35b5acb6-282f-44d5-8037-b0c472c81aab.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MTI1MTkxNDQsIm5iZiI6MTcxMjUxODg0NCwicGF0aCI6Ii8xODgxODE5Ni8zMTg2ODEwMzAtMzViNWFjYjYtMjgyZi00NGQ1LTgwMzctYjBjNDcyYzgxYWFiLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNDA0MDclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjQwNDA3VDE5NDA0NFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBkMThjYWUwYjA2MDYxNDhlNWZjNTc2YzVlYzc3YWNlODQzYzJhMjM4OTI2MTQ1NjU2OTJjNjA5YjI5NGE0NmQmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0JmFjdG9yX2lkPTAma2V5X2lkPTAmcmVwb19pZD0wIn0.dM1XLx0LgJPx7ayjL21-JEg7hpg_4ArrJ3VdpDe4MCA">

Same dangling line here. You can filter it out:

code > .line:not(:last-child)::before {
 /* styling */
}

@MatthewAry
Copy link

@antfu Would love to see this solution on the Shiki docs.

@antfu
Copy link
Member

antfu commented May 8, 2024

PR welcome :)

@lloydjatkinson
Copy link

@antfu Would love to see this solution on the Shiki docs.

You can also checkout https://expressive-code.com/ which uses Shiki and has a line number option

@jimfilippou
Copy link

Extending on @alexpeattie's answer, if you're looking to get rid of the last line that this code adds, feel free to use the following code.

code .line:last-child::before {
  content: 'none';
}

@eniodev
Copy link

eniodev commented Jun 13, 2024

@seancheung another way of getting rid of that extra line:

code .line:last-child:empty::before {
  content: none;
  counter-increment: none;
}

@michael-andreuzza
Copy link

As an alternative to writing a custom renderToHtml function: since v0.2.3 each line is wrapped in a <span class='line'> which makes it quite easy to do line numbering using CSS counters. I added some CSS like this:

code {
  counter-reset: step;
  counter-increment: step 0;
}

code .line::before {
  content: counter(step);
  counter-increment: step;
  width: 1rem;
  margin-right: 1.5rem;
  display: inline-block;
  text-align: right;
  color: rgba(115,138,148,.4)
}

Which yields: Capture d’écran 2021-05-01 à 08 35 14

You my day :-) Thank you.

@LekoArts
Copy link

LekoArts commented Aug 6, 2024

Regarding the dangling new line when used in Astro:

You can remove it like so in your astro.config.ts

import { defineConfig } from 'astro/config'

// https://astro.build/config
export default defineConfig({
	markdown: {
		syntaxHighlight: 'shiki',
		shikiConfig: {
			transformers: [
				{
					preprocess(code) {
						if (code.endsWith('\n')) {
							code = code.slice(0, -1)
						}

						return code
					},
				},
			],
		},
	},
})

@lilpolymath
Copy link

@antfu do you have any reservations on how the transformer for this should be implemented?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.