(function () { if (typeof Prism === 'undefined' || typeof document === 'undefined') { return; } // Copied from the markup language definition var HTML_TAG = /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/g; // a regex to validate hexadecimal colors var HEX_COLOR = /^#?((?:[\da-f]){3,4}|(?:[\da-f]{2}){3,4})$/i; /** * Parses the given hexadecimal representation and returns the parsed RGBA color. * * If the format of the given string is invalid, `undefined` will be returned. * Valid formats are: `RGB`, `RGBA`, `RRGGBB`, and `RRGGBBAA`. * * Hexadecimal colors are parsed because they are not fully supported by older browsers, so converting them to * `rgba` functions improves browser compatibility. * * @param {string} hex * @returns {string | undefined} */ function parseHexColor(hex) { var match = HEX_COLOR.exec(hex); if (!match) { return undefined; } hex = match[1]; // removes the leading "#" // the width and number of channels var channelWidth = hex.length >= 6 ? 2 : 1; var channelCount = hex.length / channelWidth; // the scale used to normalize 4bit and 8bit values var scale = channelWidth == 1 ? 1 / 15 : 1 / 255; // normalized RGBA channels var channels = []; for (var i = 0; i < channelCount; i++) { var int = parseInt(hex.substr(i * channelWidth, channelWidth), 16); channels.push(int * scale); } if (channelCount == 3) { channels.push(1); // add alpha of 100% } // output var rgb = channels.slice(0, 3).map(function (x) { return String(Math.round(x * 255)); }).join(','); var alpha = String(Number(channels[3].toFixed(3))); // easy way to round 3 decimal places return 'rgba(' + rgb + ',' + alpha + ')'; } /** * Validates the given Color using the current browser's internal implementation. * * @param {string} color * @returns {string | undefined} */ function validateColor(color) { var s = new Option().style; s.color = color; return s.color ? color : undefined; } /** * An array of function which parse a given string representation of a color. * * These parser serve as validators and as a layer of compatibility to support color formats which the browser * might not support natively. * * @type {((value: string) => (string|undefined))[]} */ var parsers = [ parseHexColor, validateColor ]; Prism.hooks.add('wrap', function (env) { if (env.type === 'color' || env.classes.indexOf('color') >= 0) { var content = env.content; // remove all HTML tags inside var rawText = content.split(HTML_TAG).join(''); var color; for (var i = 0, l = parsers.length; i < l && !color; i++) { color = parsers[i](rawText); } if (!color) { return; } var previewElement = ''; env.content = previewElement + content; } }); }());