Skip to content

Instantly share code, notes, and snippets.

@hackjutsu
Last active November 16, 2022 14:16
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save hackjutsu/0a6338d66f4fd7d338fd0c04f3454394 to your computer and use it in GitHub Desktop.
Save hackjutsu/0a6338d66f4fd7d338fd0c04f3454394 to your computer and use it in GitHub Desktop.
[Highlight.js + line number] This snippet adds line number support to Highlight.js. Besides, special css trick is applied to stop the line numbers from being selected and copied. #tags: highlight, lepton
import HighlightJS from 'highlight.js'
createHighlightedCodeBlock (content, language) {
let lineNumber = 0
const highlightedContent = HighlightJS.highlightAuto(content, [language]).value
/* Highlight.js wraps comment blocks inside <span class="hljs-comment"></span>.
However, when the multi-line comment block is broken down into diffirent
table rows, only the first row, which is appended by the <span> tag, is
highlighted. The following code fixes it by appending <span> to each line
of the comment block. */
const commentPattern = /<span class="hljs-comment">(.|\n)*?<\/span>/g
const adaptedHighlightedContent = highlightedContent.replace(commentPattern, data => {
return data.replace(/\r?\n/g, () => {
return '\n<span class="hljs-comment">'
})
})
const contentTable = adaptedHighlightedContent.split(/\r?\n/).map(lineContent => {
return `<tr>
<td class='line-number' data-pseudo-content=${++lineNumber}></td>
<td>${lineContent}</td>
</tr>`
}).join('')
return `<pre><code><table class='code-table'>${contentTable}</table></code></pre>`
}
/*
* Transform the snippet from plain text to html markup which includes line number
* support. This method returns an object that can be consumed by a React component.
* @content plain text for snippet
* @language the language for the snippet
*/
createMarkup (content, language) {
return { __html: this.createHighlightedCodeBlock(content, language) }
}
// Consumed by React
// <div dangerouslySetInnerHTML={ this.createMarkup(content, language) }/>
.line-number {
text-align: right;
padding-right: 20px;
display: inline-block;
color: rgba(0,0,0,0.2);
width: 40px;
font-size: 11px;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
}
/* Technique to disable line numbers from being selected and copied.
Checkout this post for more details http://codepen.io/danoc/pen/ByGKZv */
[data-pseudo-content]::before,
[data-pseudo-content--before]::before,
[data-pseudo-content--after]::after {
content: attr(data-pseudo-content);
}
@mberneti
Copy link

well done

@arenn23
Copy link

arenn23 commented Jul 1, 2021

Very well done. Thank you so much.

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