The Website

This website is hosted through GitHub pages and thus can't run any server side code, meaning: everything you see here was made using html, css and javascript! Even the syntax highlighting is generated on the fly using javascript without any library. I found this blog describing how the author created a simple syntax highlighting logic using nothing but css and javascript. I've copied and modified the code to work for any width and length and worked with the <code> tag instead of the <pre> tag.

It's actually quite simple: You take a list of objects containing a regex, color and ident like this:

const cRegex = [
	{
		regex: /"(.*?)"/g, // strings
		val: '#FFD658',
		code: 'A'
	},
	{
		regex: /(\d+\.?)/g, // numbers
		val: ' #A7C',
		code: 'B'
	},
	{
		regex: /\b(char|short|int|long|float|double|unsigned|void|const|static|typedef|struct|[^\s]+_t)\b/g, // keywords and types
		val: '#78dce8',
		code: 'C'
	},
	{
		regex: /(\w[A-Za-z0-9_]*)(?=\()/g, // functions
		val: '#a6e22e',
		code: 'D'
	},
	{
		regex: /\b(sizeof|delete|switch|case|if|else|extern|return|for|while|break|continue|include)\b/g, // commands
		val: '#E68',
		code: 'E'
	},
	{
		regex: /\b(true|false|NULL|\$)(?=[^\w])/g, // constants
		val: '#ae81ff',
		code: 'F'
	},
	{
		regex: /([\b\s])([!=]=|[!=]==|\+\+|--|&&|\|\|<=|>=|>>|<<|\.\.\.)(?!span)([\b\s\w])/g, // operators
		val: '#f92672',
		code: 'G'
	},
	{
		regex: /(\/\/.*)/g, // single line comment
		val: 'gray',
		code: 'H'
	},
];

Then you just tokenize the input based on these regex expressions and parse them into a linear gradient using the index, length and color value given to the code:

function findTokens(line, regexObjs){
    var rtrnText = '0'.repeat(line.length); // This string will hold the required information once tokenized
    
    for(x = 0; x < regexObjs.length; x++){
        
        let matches = [...line.matchAll(regexObjs[x].regex)];
        
        matches.forEach((match) => {
			// the <code> tag doesn't reconize '\n' symbols as characters when drawing the linear-gradient and thus we'll need to exclude them when writing the character index
            rtrnText = rtrnText.replaceAt(match.index-(match.index-line.slice(0, match.index).replaceAll('\n', '').length), match[0].length, regexObjs[x].code);
        });
    }
    return rtrnText;
}



function convertToCSS(line, regexObjs){
    let rtrnString = 'linear-gradient(to right, ';
    let previousChar = '';
    let previousColour = 'white';    
    
    for(z = 0; z < line.length; z++){
        if(line[z] != previousChar){
            
            if(line[z] == 0){
                rtrnString += previousColour + ' ' + z + 'ch, white ' + z + 'ch, '; 
                previousChar = '0';
                previousColour = 'white';
            }else{
                for(a = 0; a < regexObjs.length; a++){
                    if(line[z] == regexObjs[a].code){
                        rtrnString += previousColour + ' ' + z + 'ch, ' + regexObjs[a].val + ' ' + z + 'ch, '; 
                        previousChar = line[z];
                        previousColour = regexObjs[a].val;
                    }
                }
            }
        }
    }
    rtrnString += 'white ' + line.replaceAll('\n', '').length + 'ch)';
    return rtrnString;
}

console.log(convertToCSS(findTokens('char *str = "Hello world!";\nint main(int argc, char **argv)\n{\n    printf("%s\n", str);\n    return 0;\n}', cRegex), cRegex));