How to Exclude Code Line Numbers from Selection in Jekyll
Note: This trick no longer works due to how line numbers are currently generated.
I ran into an issue when trying to use the linenos
option for highlighting code with Jekyll and pygments. I didn’t like that the default version allowed you to select the line numbers when copying and pasting. The table version also has many issues (see this post). I didn’t like the idea of having to write javascript to get around this. The problem seemed to me like it could be solved in a much simpler fashion. My solution was to add the following scss to my site:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
code {
counter-reset: linenumber; // reset the counter every time we start a new code block
}
.lineno {
visibility: hidden; // I want to hide the selectable line number
font-size: 0; // this makes it so the hidden content takes up no space
&::before {
font-size: 1rem; // use rem since the em would be relative to 0 font-size above
content: "" counter(linenumber); // display the current line number count (
counter-increment: linenumber; // increment the line number each time it's rendered
visibility: visible; // override parent's hidden
display: inline-block; // so we can specify a width
width: 1rem; // give us enough width to pad the line number
// should work unless I decide to blog over 1000 lines
// ... which I don't plan on doing anyways
}
}
// notice that copying and pasting from this code block does not include the line numbers
This allowed me to avoid having to fix this ugly monstrosity (it’s the same code as above, just using linenos=table
):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
code {
counter-reset: linenumber; // reset the counter every time we start a new code block
}
.lineno {
visibility: hidden; // I want to hide the selectable line number
font-size: 0; // this makes it so the hidden content takes up no space
&::before {
font-size: 1rem; // use rem since the em would be relative to 0 font-size above
content: "" counter(linenumber); // display the current line number count (
counter-increment: linenumber; // increment the line number each time it's rendered
visibility: visible; // override parent's hidden
display: inline-block; // so we can specify a width
width: 1rem; // give us enough width to pad the line number
// should work unless I decide to blog over 1000 lines
// ... which I don't plan on doing anyways
}
}
// notice that copying and pasting from this code block does not include the line numbers
Another benefit is that I can take advantage of the initial counter increment. I added a new html file in my _include
directory with the following content:
1
2
3
4
5
6
<style>
#offset-{{ include.offset }} + .highlight code {
counter-increment: linenumber {{ include.offset }};
}
</style>
<div id="offset-{{ include.offset }}"></div>
So now, when I add {% include line_number_offset.html offset="5" %}
I can produce the following:
1
2
3
4
This is some sample text.
Note that the offset adds to the 1.
So an offset of 5 is 1+5, which comes out to the 6
you see on the first line
I just have to make sure I don’t include any text or tags in between the include
and the highlight
liquid tags. If I do, the offset won’t apply. This is caused by the +
in the css rule. I prefer it this way so I don’t accidentally offset the line numbers in more than one code block.
Let me know what you think of this article on twitter @Nashenas88 or leave a comment below!