Skip to content

Instantly share code, notes, and snippets.

@AsyncWizard
Last active January 5, 2024 11:12
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save AsyncWizard/c6017edff56c08ab37189939e0e5d012 to your computer and use it in GitHub Desktop.
Save AsyncWizard/c6017edff56c08ab37189939e0e5d012 to your computer and use it in GitHub Desktop.
Trello markdown code syntax highlight.
// ==UserScript==
// @name Trello Syntax Highlight
// @namespace https://gist.github.com/AsyncWizard
// @version 0.1
// @description try to take over the world!
// @author AsyncWizard
// @require https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/highlight.min.js
// @resource https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/github.min.css
// @match https://trello.com/*
// @grant none
// @updateURL https://gist.github.com/AsyncWizard/c6017edff56c08ab37189939e0e5d012/raw/trello-md-code-highlight.js
// @downloadURL https://gist.github.com/AsyncWizard/c6017edff56c08ab37189939e0e5d012/raw/trello-md-code-highlight.js
// ==/UserScript==
(function() {
'use strict';
function observeChildList(target, callback){
// create an observer instance
var observer = new MutationObserver(callback);
// configuration of the observer:
// TODO: Check this conf
var config = {
//attributes: true,
childList: true,
//characterData: true
};
// pass in the target node, as well as the observer options
observer.observe(target, config);
}
function highlight(md){
/*
Observation des changements sur la carte.
Il se peut que la description change, dans ce cas il faut la re-highlighter
On va ajouter un attribut au node et s'en servir afin de ne l'observer qu'une fois.
Lorsqu'on se trouve dans le callback, on supprime l'attribut card-highlighted afin de relancer l'highlight
Observing changes on the card.
         It may be that the description changes, in this case we need to re-highlighting
         We will add an attribute to the node and use it to observe node only once.
         When we are into the callback, we remove the card-highlighted attribute in order to restart the highlight
*/
if(md.getAttribute('card-observed')!=='true'){
md.setAttribute('card-observed',"true");
observeChildList(md, function(mutations){
for(let mutation of mutations){
if(mutation.type=='childList'){
if(md){
md.removeAttribute('card-highlighted');
highlight(md);
break;
}
}
}
});
}
if(!md.hasChildNodes()
|| md.getAttribute('card-highlighted')==="true"
)return;
md.setAttribute('card-highlighted',"true");
/**
Démarrage de la procédure d'highlight
Starting highlighting procedure
**/
let $md = $(md), preLngList = [], isBlockOpen=true;
/*
On récupère la liste des code-blocks du markdown pour la mettre dans le tableau:
On ne tient pas compte des code-blocks de fermeture
On utilise deux fonctions afin de gérer le codeblock du début de message
*/
/*
We retrieve the list of code-blocks from the markdown to put it in the array:
The closing code-block are not taken into consideration
Two functions are used to manage the code-block of the beginning of the message
*/
let mdContent = $md.data('unmarkeddown');
mdContent.replace(/^[\r\n]*```([A-Za-z0-9+\-\.]+)?\r?\n((.|\r|\n|\s)+?)```/g, function(fouded, lng){
preLngList.push(lng);
});
mdContent.replace(/\r?\n\r?\n```([A-Za-z0-9+\-\.]+)?\r?\n((.|\r|\n|\s)+?)```/g, function(fouded, lng){
preLngList.push(lng);
});
//Adding code tag class with good highlighter/language class
md.querySelectorAll('pre > code').forEach(function(code, id){
let language = preLngList[id];
if(language){
//Changing parent for removing padding and grey color
code.parentNode.className += ' hljs';
//code.parentNode.style.padding=0;
code.className += ' ' + language;
hljs.highlightBlock(code);
}
});
}
$(document).ready(function() {
// head CSS injection by link tag (I can't make it work otherwise)
$("head")
.append (
'<link href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.11.0/styles/github.min.css" rel="stylesheet" type="text/css">'
)
.append(
`<style>
.window-wrapper.js-tab-parent .hljs{
background: #e2e4e6;
/* Keeping initial scrollbar */
overflow-x: initial;
}
</style>`
)
;
var target = document.querySelector('.window-wrapper.js-tab-parent');
observeChildList(document.querySelector('.window-wrapper.js-tab-parent'), function(mutations) {
for(let mutation of mutations){
if(mutation.type=='childList'){
let md = target.querySelector('.current.markeddown.hide-on-edit.js-card-desc.js-show-with-desc');
if(md){
highlight(md);
break;
}
}
}
});
});
})();
@applejag
Copy link

Works wonders! Kudos!

@AsyncWizard
Copy link
Author

@jilleJr Thank you! Glad to read your return!

@ai7ch
Copy link

ai7ch commented Apr 2, 2020

@jilleJr Thank you! Glad to read your return!

@AsyncWizard How can I use this in my trello?

@mmcguff
Copy link

mmcguff commented May 7, 2020

So for those that are stumbling upon this like I did, a userscript is a special bit of JavaScript code you can run as a script in your browser. An chrome extension called tampermonkey allows you to run your own custom scripts that will alter behavior of particular web sites and app you access through your browser.

That being said this script basically will work on the in the browser version of this. This would need to be added as a feature in order to be part of Trello for real. Thanks for sharing this.

@AsyncWizard
Copy link
Author

@jilleJr Thank you! Glad to read your return!

@AsyncWizard How can I use this in my trello?

Hi @ai7ch,

As @mmcguff said, I wrote this script for the brower version of Trello.
You need an extension called tampermonkey for chromium (or greasemonkey for firefox) which allows you to run javascript code on web pages.
Thus, on the Trello page, you will have the possibility of executing this script which will process the code blocks in the markdown of the cards.
I have to say that I haven't used Trello for a while. I don't know how things are going with the webpage or apps.

Thank you all for your feedback. If it becomes necessary, I will add a presentation markdown on this gist.

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