Oznaczanie języka przy prezentacji kodu na stronie
• tech • 711 słów • 4 minuty czytania
Prezentując na stronie różne fragmenty kodu, czy to w formie pokolorowanej czy surowej, często nie podaje się oznaczenia języka. W końcu z kontekstu i składni wynika co to jest, choć nie zawsze łatwo jest to wydedukować. W związku z tym wpadłem na pomysł, aby “label” z identyfikatorem języka pojawił się obok wyświetlanego kodu.
Na początku myślałem, że uda mi się zmusić jakoś Hugo/Chroma do dodawania takiej informacji do generowanej strony. Ale gdy takowej możliwości nie znalazłem słuszne wydawało się zastosowanie do tego celu JS-a. Nie będę przecież dodawał jakiś specjalnych shortcodes sobie do kontentu. W końcu to tylko “upiększacz” to niech po stronie klienta sobie to przeglądarka “renderuje”. A skoro to tylko ozdobnik do prezentacji to dodatkowe tagi w kodzie lub elementy w DOM strony też nie bedą dobrym pomysłem - semantyka, clean-content. Trzeba to zrobić inaczej, czyli w CSS-sie ;)
Wypluwany przez (koloro-)generatory (tutaj chroma) kod jest zazwyczaj odpowiednio otagowany:
<div class="highlight">
<pre class="chroma">
<code class="language-js" data-lang="js">
[...]
</code>
</pre>
</div>
Mając w atrybutach informacje o języku zawartego w elemencie kodu, bez problemu za pomocą selektorów atrybutu i pseudoelementów CSS można stworzyć takie “labele” wyświetlające nazwę (identyfikator) języka dołączonego kodu.
pre code[class=language-js]::before {
content: "js";
/* stylowanie i pozycjonowanie */
}
Dodanie takowych styli do każdej używanej na stronie składni kodu może być trochę upierdliwe. Na szczęście, gdy jest dostępny atrybut z “czystą” zawartością nadającą się bezpośrednio do prezentacji można skorzystać z bardziej generycznego sposobu z użyciem attr()
:
pre code[data-lang]::before {
content: attr(data-lang);
/* stylowanie i pozycjonowanie */
}
Niekiedy jednak może się zdarzyć, że chcielibyśmy inaczej oznaczyć kod - innym identyfikatorem, pełną nazwą lub zunifikować używane w różnych miejscach identyfikatory lub skróty danego języka. Wtedy jednak trzeba dodać te poszczególne elementy “nadpisując” kaskadowo domyślną wartość otrzymywaną z attr()
.
pre code[data-lang]::before {
content: attr(data-lang);
}
pre code[data-lang=js]::before,
pre code[data-lang=javascript]::before
{
content: "JS";
}
pre code[data-lang=cpp]::before,
pre code[data-lang=c++]::before,
pre code[data-lang=cplusplus]::before
{
content: "C++";
}
Mi to nie powinno grozić bo będę trzymał się jednego identyfikatora, a pomagać mi w tym będą jakieś skrypty weryfikujące spójność stylu i użytych elementów w moich Markdown-owych plikach z treściami. Sam nie wiem, czy lepsze będą proste i ogólne znane identyfikatory, czy może skrócone lub pełne nazwy, bądź mieszanka… ale na pewno, co ważne, będą one spójne we wszystkich miejscach!
Co do stylowania i pozycjonowania miejsca usytuowania etykiety, to rozważam dwie opcje - w środku elementu z kodem lub bezpośrednio nad nim (akurat trafi w marginesie) po prawej stronie. Podgląd obu wariantów na poniższym obrazku.
Obie wersje bardzo łatwo otrzymać z pomocą szczypty CSS-a pozycjonując i ewentualnie według upodobania stylizując etykietę. Oczywiście w jakimś mniej rzucającym się kolorze, aby nie odciągać od głównej zawartości strony (kodu).
pre {
--padding-x: 1em;
--padding-y: .8em;
padding: var(--padding-y) var(--padding-x);
position: relative;
}
pre code::before {
content: attr(data-lang);
position: absolute;
color: #ccc;
/* inside pre/code element */
top: var(--padding-y);
right: var(--padding-x);
/* above pre/code element */
/* top: -1lh; line-height unit not supported yet */
line-height: 1.3;
top: calc(1.3 * -1em);
right: 0.25em;
}
Tym sposobem, za pomocą kilku linijek prostego CSS-a, udało się nieco wzbogacić prezentacje kodu na stronie. Może to wydawać się banalne, ale idealnie pokazuje to, jak małym wysiłkiem można poprawić użyteczność strony. Oczywiście przedstawiony sposób jest minimalistyczny i może być dobrym punktem wyjścia do dalszej rozbudowy. Takim ulepszeniem może być chociażby rozwijanie skrótu/identyfikatora w etykiecie do pełnej nazwy języka po najechaniu myszką na kod… lub co tam sobie ktoś wymyśli ;)
Mimo, że powyższe fragmenty dotyczą stricte kodu generowanego przez Hugo, w końcu na niego przesiadam się z tym blogiem, to idea jest tak prosta, że można ją zaadoptować do każdej innej strony/generatora.
Obecnie na tej stronie (w czasie pisania tego wpisu) na WordPress-ie używany jest jakiś stary plugin - WP-CodeBox, bazujący na silniku GeSHi. Wynikowy kod HTML-a z pokolorowaną składnią przedstawia się następująco:
<div class="wp_codebox">
<table>
[...]
<pre class="cpp" style="font-family:monospace;">
[...]
</pre>
[...]
</table>
</div>
Trochę “napaćkane” dodatkowymi elementami, ale docelowy <pre/>
zawiera klasę z nazwą wyświetlanego języka. Zatem wszystko jest podobne, a różni się jedynie selektorami i nazwami elementów/atrybutów.
Dodanie do aktualnych styli na stronie poniższego fragmentu robi swoja robotę!
.wp_codebox pre {
position: relative;
}
.wp_codebox pre::before {
content: attr(class);
position: absolute;
top: 0;
right: 0;
color: #aaa;
}
I w takim stanie też pozostanie do końca swojego żywota - przejścia na Hugo ;)
Komentarze (0)