0

I have a Hugo-generated static website and in each code snippet I want to place the language name in the bottom right.

I am already able to get the whole class (language-x) in the code tag using a CSS selector but I want to capture only the language name from the class name, not the whole class.

This is a minimum working example of what I have so far:

https://codepen.io/anon/pen/gZWWNP

<html>

<style>
pre {
    background: #26282C;
    color: #fff;
    text-align: left;
    padding: 0.5em;
    padding-left: 0.5em;
    padding-left: .8em;
    word-break: break-all;
    white-space: pre-wrap;
    overflow: auto;
    tab-size: 4;
    margin-bottom: 20px;
    border-left: 5px solid #F27563;
    border-bottom-right-radius: 5px;
    border-top-right-radius: 5px;
}

code[class*="language-"]:after,
pre[class*="language-"]:after {
  content: attr(class);
  color: #fff;
  font-size: smaller;
  font-weight: bold;
  display: block;
  text-align: right;
  padding-top: 5px;
}
</style>

<body>

<pre>
<code class="language-perl6">class Person {
    has Str $.firstname;
    has Str $.lastname;
    has Str $.age;
}
</code>
</pre>

</body>
</html>

In this case, instead of language-perl6 I'd like to display just perl6. I want to keep this as minimal as possible without using any additional tool besides CSS or probably vanilla JS.

1 Answer 1

1

You can't update the content value unfortunately, but you can create a new attr via javascript and use this within your CSS. I have referenced a new attribute within your CSS - content: attr(short-lang);, and then written some pure javascript to convert your class and assign it to the new attribute.

I've created the code so it works for pre and code elements as this is what your CSS suggests is needed. I added a pre with a class to the demo.

I would seriously consider storing the language in it's own attribute, rather than as a class as if you have to add any other class this code will also display those classes.

// Get all code and pre elements
var elements = document.querySelectorAll('code,pre');

// Cycle through each code element
for (var i = 0; i < elements.length; i++) {

    // Load language from class
    var lang = elements[i].getAttribute("class");
    
    // Remove 'language-' if lang is not empty
    if (lang != null ) {
      lang = lang.substr(lang.length - (lang.length-9));
    }
    
    // Create 'short-lang' parameter for element
    elements[i].setAttribute("short-lang", lang);
    
}
pre {
    background: #26282C;
    color: #fff;
    text-align: left;
    padding: 0.5em;
    padding-left: 0.5em;
    padding-left: .8em;
    word-break: break-all;
    white-space: pre-wrap;
    overflow: auto;
    tab-size: 4;
    margin-bottom: 20px;
    border-left: 5px solid #F27563;
    border-bottom-right-radius: 5px;
    border-top-right-radius: 5px;
}

code[class*="language-"]:after,
pre[class*="language-"]:after {
  content: attr(short-lang);
  color: #fff;
  font-size: smaller;
  font-weight: bold;
  display: block;
  text-align: right;
  padding-top: 5px;
}
<html>


<body>

<pre>
<code class="language-perl6">
class Person {
    has Str $.firstname;
    has Str $.lastname;
    has Str $.age;
}

</code>

</pre>

<pre class="language-perl9">
class Person {
    has Str $.firstname;
    has Str $.lastname;
    has Str $.age;
}


</pre>

</body>
</html>

Sign up to request clarification or add additional context in comments.

1 Comment

This works wonderfully. I'm unsure how I'd instruct Hugo to store the language in its own attribute though but I'll leave it for another time. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.