As I might have said earlier, I will have to display a lot of code in the future. Blogger's Wysiwyg HTML editor provides a way to format the code but it is highly insufficient. I'd rather use something more powerful and beautiful to avoid having unreadable code snippets in the future that I won"t distinguish from normal text.
I don't know if it's luck or the fact that the library I'm gonna use has also been developed by Google, but Blogger editor, when being asked to format code wraps it into a <pre> tag. it seems that this tag is one of those supported by the code-prettify.
My first idea was to add a class attribute with prettyprint to the tag and let the library automatically detect the language that I am using, but now that I've read the documentation, I highly doubt that the library will have 100% of positive programming language detection. So I must help it by adding a lang-* class to the class attribulte.
Another problem lies in the fact that not all the pages need that library, so I need to load it only when code is present on a page. That will save additional loading time.
Since the code of all different types of pages is contained into the same XML file, I will specify to load the library only on an article page. According to blogger documentation they call it an item page.
<b:if cond='data:blog.pageType == "item"'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js" async></script>
</b:if>
I must also call it only if code is present on the page, so if at least one prettyprint class exists in the dom. Since the library also fetches the dom the find prettyprint tags, i do not have to do that. I'll just do as explained in the documentation and call prettiprint function as body finishes loading.
<body onload='PR.prettyPrint()'>
One problem persists though. WIth this code i will have an error on every "non item" page, because the eventlistner on body will try to call the method prettyprint on a non initiated object of non existing library. To avoid that, I place the loading event in the previous condition and call it when the library is loaded "defer".
<b:if cond='data:blog.pageType == "item"'>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js" defer></script>
</b:if>
const scriptTag = Array.prototype.filter.call(
document. getElementsByTagName('script') ,
function (e) {return e.src.indexOf('https://cdnjs.cloudflare.com/ajax/libs/prettify/r298/prettify.min.js') >= 0;}
)[0];
scriptTag.addEventListener('load', () => {
function ready(fn) {
if (document.readyState != 'loading'){
fn();
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
ready(PR.prettyPrint());
})
No comments: