Si tienes un blog que trata sobre desarrollo, es probable que hayas tenido que mostrar código a tus usuarios. Es por eso que hoy te muestro como agregar un resaltador de código que cuenta con un botón para copiar, que además he optimizado para solo cargar el script cuando sea necesario.
Instalar
Primero vas a necesitar incluir los siguientes estilos en tu proyecto. Por ejemplo, si usas WordPress puedes incluirlo en el archivo style.css
. En Blogger debes usar la opción Agregar CSS de la plantilla. Para todos los demás, puedes incluirlo en el <head>
de tu sitio.
pre {
--copy-text: "Copy";
--copied-text: "Copied!";
--code-bg: #2a2833;
--code-color: #9a92be;
--code-color-comment: #787878;
--code-color-string: #ffcd81;
--code-color-selector: #a38eff;
--code-color-property: #a38eff;
--code-color-tag: #6a6684;
--code-color-tag-name: #eeebfe;
--code-color-attr: #c3b6ff;
--code-color-class: #eeebff;
--code-color-number: #ffcd95;
position: relative;
font-family: SFMono-Regular, monospace;
}
pre > code {
background-color: var(--code-bg);
color: var(--code-color);
display: block;
overflow-x: auto;
white-space: pre;
padding: 1.5rem;
border-radius: 0.5rem;
}
.hljs-copy {
position: absolute;
border: 0 none;
inset: 0.5rem 0.5rem auto auto;
padding: 0.5rem 0.75rem;
background-color: rgba(0, 0, 0, 0.5);
color: #fff;
cursor: pointer;
border-radius: 0.5rem;
transition: 0.3s background-color;
font-size: 14px;
}
.hljs-copy:hover { background-color: rgba(0, 0, 0, 0.75) }
.hljs-copy::before { content: var(--copy-text) }
.hljs-copy.is-copied::before { content: var(--copied-text) }
.hljs-name,
.hljs-section { color: var(--code-color-tag-name) }
.hljs-tag { color: var(--code-color-tag) }
.hljs-selector-class { color: var(--code-color-class) }
.hljs-number { color: var(--code-color-number) }
.hljs-comment,
.hljs-meta { color: var(--code-color-comment) }
.hljs-emphasis,
.hljs-quote,
.hljs-string,
.hljs-strong,
.hljs-template-variable,
.hljs-variable { color: var(--code-color-string) }
.hljs-keyword,
.hljs-selector-tag,
.hljs-type { color: var(--code-color-selector) }
.hljs-attribute,
.hljs-bullet,
.hljs-literal,
.hljs-symbol { color: var(--code-color-property) }
.hljs-attr,
.hljs-selector-attr,
.hljs-selector-id,
.hljs-selector-pseudo,
.hljs-title { color: var(--code-color-attr) }
Ahora el script, el cual se encargará de agregar el botón de copiar y de cargar el resaltador de código. Debes incluirlo arriba de tu etiqueta </body>
o si posees un archivo main.js
puedes incluirlo ahí.
<script>/*<![CDATA[*/
async function initHighlight() {
const loadScript = () => new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = 'https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11/build/highlight.min.js'
script.onload = resolve
script.onerror = reject
document.body.appendChild(script)
})
try {
await loadScript()
hljs.highlightAll()
} catch (error) {
console.error(error)
}
}
function addCopyButtons (codeBlock) {
if (!navigator || !navigator.clipboard) return
const clipboard = navigator.clipboard
const $button = document.createElement('button')
$button.className = 'hljs-copy'
$button.addEventListener('click', function () {
clipboard.writeText(codeBlock.textContent).then(function () {
$button.blur()
$button.classList.add('is-copied')
$button.disabled = true
setTimeout(function () {
$button.disabled = false
$button.classList.remove('is-copied')
}, 2000)
})
})
const pre = codeBlock.parentNode
pre.insertBefore($button, pre.firstChild)
}
function initCodeBlocks () {
const codeBlocks = document.querySelectorAll('pre > code')
if (codeBlocks.length === 0) return
initHighlight()
codeBlocks.forEach(function (codeBlock) {
addCopyButtons(codeBlock)
})
}
initCodeBlocks()/*]]>*/
</script>
Lo que hace este script es agregar un botón que al hacer clic copia el contenido del código. Además, carga el resaltador de código, pero solo realizará ambas acciones cuando exista al menos un bloque de código en la página.
Modo de uso
Para usarlo solo debes agregar un bloque de código en tu página. Entendiendo que el código debe estar dentro de una etiqueta <pre>
y <code>
como se muestra a continuación:
<pre><code>
// Tu código aquí
</code></pre>
Por lo general highlightJs detectará el lenguaje que haz utilizado, pero para los casos que esto no sea suficiente o falle, puedes especificar el lenguaje usando una clase:
<pre><code class="language-html">
// Tu código aquí
</code></pre>
Además recuerda que es muy importante que todo el código HTML se encuentre escapado. Para ayudarte con esta tarea he desarrollado una herramienta para escapar código html que puedes usar.
Personalizar
Si deseas personalizar el resaltador de código, puedes hacerlo modificando las variables que se encuentran al inicio del código CSS. Estas variables son las que se encargan de cambiar los colores del resaltador de código y otros estilos importantes.
He tratado de ser muy descriptivo con los nombres de las variables, pero si tienes alguna duda puedes preguntarme en los comentarios. Por si te lo preguntas, los estilos están inspirados del tema Duotone Dark del desarrollador Simurai.
Observaciones
Ten en cuenta que en todo el articulo se asume que usas los bloques <pre>
y <code>
solo para mostrar código. Si usas estas etiquetas para mostrar otro tipo de contenido, es probable que necesites realizar algunos cambios.
Conclusión
Realmente deseo que este articulo te haya ayudado de alguna forma si llegaste aquí buscando una solución para agregar un resaltador de código con un botón para copiar. Si tienes alguna duda o sugerencia puedes dejarla en los comentarios.