/** * HTML operations. * * @author n1474335 [n1474335@gmail.com] * @copyright Crown Copyright 2016 * @license Apache-2.0 * * @namespace */ const HTML = { /** * @constant * @default */ CONVERT_ALL: false, /** * @constant * @default */ CONVERT_OPTIONS: ['Named entities where possible', 'Numeric entities', 'Hex entities'], /** * To HTML Entity operation. * * @param {string} input * @param {Object[]} args * @returns {string} */ run_to_entity(input, args) { let convert_all = args[0], numeric = args[1] == 'Numeric entities', hexa = args[1] == 'Hex entities'; const charcodes = Utils.str_to_charcode(input); let output = ''; for (let i = 0; i < charcodes.length; i++) { if (convert_all && numeric) { output += `${charcodes[i]};`; } else if (convert_all && hexa) { output += `${Utils.hex(charcodes[i])};`; } else if (convert_all) { output += HTML._byte_to_entity[charcodes[i]] || `${charcodes[i]};`; } else if (numeric) { if (charcodes[i] > 255 || HTML._byte_to_entity.hasOwnProperty(charcodes[i])) { output += `${charcodes[i]};`; } else { output += Utils.chr(charcodes[i]); } } else if (hexa) { if (charcodes[i] > 255 || HTML._byte_to_entity.hasOwnProperty(charcodes[i])) { output += `${Utils.hex(charcodes[i])};`; } else { output += Utils.chr(charcodes[i]); } } else { output += HTML._byte_to_entity[charcodes[i]] || ( charcodes[i] > 255 ? `${charcodes[i]};` : Utils.chr(charcodes[i]) ); } } return output; }, /** * From HTML Entity operation. * * @param {string} input * @param {Object[]} args * @returns {string} */ run_from_entity(input, args) { let regex = /&(#?x?[a-zA-Z0-9]{1,8});/g, output = '', m, i = 0; while (m = regex.exec(input)) { // Add up to match for (; i < m.index;) { output += input[i++]; } // Add match const bite = HTML._entity_to_byte[m[1]]; if (bite) { output += Utils.chr(bite); } else if (!bite && m[1][0] == '#' && m[1].length > 1 && /^#\d{1,5}$/.test(m[1])) { // Numeric entity (e.g. ) const num = m[1].slice(1, m[1].length); output += Utils.chr(parseInt(num, 10)); } else if (!bite && m[1][0] == '#' && m[1].length > 3 && /^#x[\dA-F]{2,8}$/i.test(m[1])) { // Hex entity (e.g. :) const hex = m[1].slice(2, m[1].length); output += Utils.chr(parseInt(hex, 16)); } else { // Not a valid entity, print as normal for (; i < regex.lastIndex;) { output += input[i++]; } } i = regex.lastIndex; } // Add all after final match for (; i < input.length;) { output += input[i++]; } return output; }, /** * @constant * @default */ REMOVE_INDENTATION: true, /** * @constant * @default */ REMOVE_LINE_BREAKS: true, /** * Strip HTML tags operation. * * @param {string} input * @param {Object[]} args * @returns {string} */ run_strip_tags(input, args) { let remove_indentation = args[0], remove_line_breaks = args[1]; input = Utils.strip_html_tags(input); if (remove_indentation) { input = input.replace(/\n[ \f\t]+/g, '\n'); } if (remove_line_breaks) { input = input.replace(/^\s*\n/, '') // first line .replace(/(\n\s*){2,}/g, '\n'); // all others } return input; }, /** * Parse colour code operation. * * @param {string} input * @param {Object[]} args * @returns {html} */ run_parse_colour_code(input, args) { var m = null, r = 0, g = 0, b = 0, a = 1; // Read in the input if (m = input.match(/#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/i)) { // Hex - #d9edf7 r = parseInt(m[1], 16); g = parseInt(m[2], 16); b = parseInt(m[3], 16); } else if (m = input.match(/rgba?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)(?:,\s?(\d(?:\.\d+)?))?\)/i)) { // RGB or RGBA - rgb(217,237,247) or rgba(217,237,247,1) r = parseFloat(m[1]); g = parseFloat(m[2]); b = parseFloat(m[3]); a = m[4] ? parseFloat(m[4]) : 1; } else if (m = input.match(/hsla?\((\d{1,3}(?:\.\d+)?),\s?(\d{1,3}(?:\.\d+)?)%,\s?(\d{1,3}(?:\.\d+)?)%(?:,\s?(\d(?:\.\d+)?))?\)/i)) { // HSL or HSLA - hsl(200, 65%, 91%) or hsla(200, 65%, 91%, 1) let h_ = parseFloat(m[1]) / 360, s_ = parseFloat(m[2]) / 100, l_ = parseFloat(m[3]) / 100, rgb_ = HTML._hsl_to_rgb(h_, s_, l_); r = rgb_[0]; g = rgb_[1]; b = rgb_[2]; a = m[4] ? parseFloat(m[4]) : 1; } else if (m = input.match(/cmyk\((\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?),\s?(\d(?:\.\d+)?)\)/i)) { // CMYK - cmyk(0.12, 0.04, 0.00, 0.03) let c_ = parseFloat(m[1]), m_ = parseFloat(m[2]), y_ = parseFloat(m[3]), k_ = parseFloat(m[4]); r = Math.round(255 * (1 - c_) * (1 - k_)); g = Math.round(255 * (1 - m_) * (1 - k_)); b = Math.round(255 * (1 - y_) * (1 - k_)); } var hsl_ = HTML._rgb_to_hsl(r, g, b), h = Math.round(hsl_[0] * 360), s = Math.round(hsl_[1] * 100), l = Math.round(hsl_[2] * 100), k = 1 - Math.max(r / 255, g / 255, b / 255), c = (1 - r / 255 - k) / (1 - k), m = (1 - g / 255 - k) / (1 - k), // jshint ignore:line y = (1 - b / 255 - k) / (1 - k); c = isNaN(c) ? '0' : c.toFixed(2); m = isNaN(m) ? '0' : m.toFixed(2); y = isNaN(y) ? '0' : y.toFixed(2); k = k.toFixed(2); let hex = `#${ Utils.pad_left(Math.round(r).toString(16), 2) }${Utils.pad_left(Math.round(g).toString(16), 2) }${Utils.pad_left(Math.round(b).toString(16), 2)}`, rgb = `rgb(${r}, ${g}, ${b})`, rgba = `rgba(${r}, ${g}, ${b}, ${a})`, hsl = `hsl(${h}, ${s}%, ${l}%)`, hsla = `hsla(${h}, ${s}%, ${l}%, ${a})`, cmyk = `cmyk(${c}, ${m}, ${y}, ${k})`; // Generate output return `${"
" + 'Hex: '}${hex}\n` + `RGB: ${rgb}\n` + `RGBA: ${rgba}\n` + `HSL: ${hsl}\n` + `HSLA: ${hsla}\n` + `CMYK: ${cmyk }`; }, /** * Converts an HSL color value to RGB. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes h, s, and l are contained in the set [0, 1] and * returns r, g, and b in the set [0, 255]. * * @private * @author Mohsen (http://stackoverflow.com/a/9493060) * * @param {number} h - The hue * @param {number} s - The saturation * @param {number} l - The lightness * @return {Array} The RGB representation */ _hsl_to_rgb(h, s, l) { let r, g, b; if (s === 0) { r = g = b = l; // achromatic } else { const hue2rgb = function hue2rgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; }, /** * Converts an RGB color value to HSL. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSL_color_space. * Assumes r, g, and b are contained in the set [0, 255] and * returns h, s, and l in the set [0, 1]. * * @private * @author Mohsen (http://stackoverflow.com/a/9493060) * * @param {number} r - The red color value * @param {number} g - The green color value * @param {number} b - The blue color value * @return {Array} The HSL representation */ _rgb_to_hsl(r, g, b) { r /= 255; g /= 255; b /= 255; let max = Math.max(r, g, b), min = Math.min(r, g, b), h, s, l = (max + min) / 2; if (max === min) { h = s = 0; // achromatic } else { const d = max - min; s = l > 0.5 ? d / (2 - max - min) : d / (max + min); switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return [h, s, l]; }, /** * Lookup table to translate byte values to their HTML entity codes. * * @private * @constant */ _byte_to_entity: { 34: '"', 38: '&', 39: ''', 60: '<', 62: '>', 160: ' ', 161: '¡', 162: '¢', 163: '£', 164: '¤', 165: '¥', 166: '¦', 167: '§', 168: '¨', 169: '©', 170: 'ª', 171: '«', 172: '¬', 173: '', 174: '®', 175: '¯', 176: '°', 177: '±', 178: '²', 179: '³', 180: '´', 181: 'µ', 182: '¶', 183: '·', 184: '¸', 185: '¹', 186: 'º', 187: '»', 188: '¼', 189: '½', 190: '¾', 191: '¿', 192: 'À', 193: 'Á', 194: 'Â', 195: 'Ã', 196: 'Ä', 197: 'Å', 198: 'Æ', 199: 'Ç', 200: 'È', 201: 'É', 202: 'Ê', 203: 'Ë', 204: 'Ì', 205: 'Í', 206: 'Î', 207: 'Ï', 208: 'Ð', 209: 'Ñ', 210: 'Ò', 211: 'Ó', 212: 'Ô', 213: 'Õ', 214: 'Ö', 215: '×', 216: 'Ø', 217: 'Ù', 218: 'Ú', 219: 'Û', 220: 'Ü', 221: 'Ý', 222: 'Þ', 223: 'ß', 224: 'à', 225: 'á', 226: 'â', 227: 'ã', 228: 'ä', 229: 'å', 230: 'æ', 231: 'ç', 232: 'è', 233: 'é', 234: 'ê', 235: 'ë', 236: 'ì', 237: 'í', 238: 'î', 239: 'ï', 240: 'ð', 241: 'ñ', 242: 'ò', 243: 'ó', 244: 'ô', 245: 'õ', 246: 'ö', 247: '÷', 248: 'ø', 249: 'ù', 250: 'ú', 251: 'û', 252: 'ü', 253: 'ý', 254: 'þ', 255: 'ÿ', 338: 'Œ', 339: 'œ', 352: 'Š', 353: 'š', 376: 'Ÿ', 402: 'ƒ', 710: 'ˆ', 732: '˜', 913: 'Α', 914: 'Β', 915: 'Γ', 916: 'Δ', 917: 'Ε', 918: 'Ζ', 919: 'Η', 920: 'Θ', 921: 'Ι', 922: 'Κ', 923: 'Λ', 924: 'Μ', 925: 'Ν', 926: 'Ξ', 927: 'Ο', 928: 'Π', 929: 'Ρ', 931: 'Σ', 932: 'Τ', 933: 'Υ', 934: 'Φ', 935: 'Χ', 936: 'Ψ', 937: 'Ω', 945: 'α', 946: 'β', 947: 'γ', 948: 'δ', 949: 'ε', 950: 'ζ', 951: 'η', 952: 'θ', 953: 'ι', 954: 'κ', 955: 'λ', 956: 'μ', 957: 'ν', 958: 'ξ', 959: 'ο', 960: 'π', 961: 'ρ', 962: 'ς', 963: 'σ', 964: 'τ', 965: 'υ', 966: 'φ', 967: 'χ', 968: 'ψ', 969: 'ω', 977: 'ϑ', 978: 'ϒ', 982: 'ϖ', 8194: ' ', 8195: ' ', 8201: ' ', 8204: '', 8205: '', 8206: '', 8207: '', 8211: '–', 8212: '—', 8216: '‘', 8217: '’', 8218: '‚', 8220: '“', 8221: '”', 8222: '„', 8224: '†', 8225: '‡', 8226: '•', 8230: '…', 8240: '‰', 8242: '′', 8243: '″', 8249: '‹', 8250: '›', 8254: '‾', 8260: '⁄', 8364: '€', 8465: 'ℑ', 8472: '℘', 8476: 'ℜ', 8482: '™', 8501: 'ℵ', 8592: '←', 8593: '↑', 8594: '→', 8595: '↓', 8596: '↔', 8629: '↵', 8656: '⇐', 8657: '⇑', 8658: '⇒', 8659: '⇓', 8660: '⇔', 8704: '∀', 8706: '∂', 8707: '∃', 8709: '∅', 8711: '∇', 8712: '∈', 8713: '∉', 8715: '∋', 8719: '∏', 8721: '∑', 8722: '−', 8727: '∗', 8730: '√', 8733: '∝', 8734: '∞', 8736: '∠', 8743: '∧', 8744: '∨', 8745: '∩', 8746: '∪', 8747: '∫', 8756: '∴', 8764: '∼', 8773: '≅', 8776: '≈', 8800: '≠', 8801: '≡', 8804: '≤', 8805: '≥', 8834: '⊂', 8835: '⊃', 8836: '⊄', 8838: '⊆', 8839: '⊇', 8853: '⊕', 8855: '⊗', 8869: '⊥', 8901: '⋅', 8942: '⋮', 8968: '⌈', 8969: '⌉', 8970: '⌊', 8971: '⌋', 9001: '〈', 9002: '〉', 9674: '◊', 9824: '♠', 9827: '♣', 9829: '♥', 9830: '♦', }, /** * Lookup table to translate HTML entity codes to their byte values. * * @private * @constant */ _entity_to_byte: { quot: 34, amp: 38, apos: 39, lt: 60, gt: 62, nbsp: 160, iexcl: 161, cent: 162, pound: 163, curren: 164, yen: 165, brvbar: 166, sect: 167, uml: 168, copy: 169, ordf: 170, laquo: 171, not: 172, shy: 173, reg: 174, macr: 175, deg: 176, plusmn: 177, sup2: 178, sup3: 179, acute: 180, micro: 181, para: 182, middot: 183, cedil: 184, sup1: 185, ordm: 186, raquo: 187, frac14: 188, frac12: 189, frac34: 190, iquest: 191, Agrave: 192, Aacute: 193, Acirc: 194, Atilde: 195, Auml: 196, Aring: 197, AElig: 198, Ccedil: 199, Egrave: 200, Eacute: 201, Ecirc: 202, Euml: 203, Igrave: 204, Iacute: 205, Icirc: 206, Iuml: 207, ETH: 208, Ntilde: 209, Ograve: 210, Oacute: 211, Ocirc: 212, Otilde: 213, Ouml: 214, times: 215, Oslash: 216, Ugrave: 217, Uacute: 218, Ucirc: 219, Uuml: 220, Yacute: 221, THORN: 222, szlig: 223, agrave: 224, aacute: 225, acirc: 226, atilde: 227, auml: 228, aring: 229, aelig: 230, ccedil: 231, egrave: 232, eacute: 233, ecirc: 234, euml: 235, igrave: 236, iacute: 237, icirc: 238, iuml: 239, eth: 240, ntilde: 241, ograve: 242, oacute: 243, ocirc: 244, otilde: 245, ouml: 246, divide: 247, oslash: 248, ugrave: 249, uacute: 250, ucirc: 251, uuml: 252, yacute: 253, thorn: 254, yuml: 255, OElig: 338, oelig: 339, Scaron: 352, scaron: 353, Yuml: 376, fnof: 402, circ: 710, tilde: 732, Alpha: 913, Beta: 914, Gamma: 915, Delta: 916, Epsilon: 917, Zeta: 918, Eta: 919, Theta: 920, Iota: 921, Kappa: 922, Lambda: 923, Mu: 924, Nu: 925, Xi: 926, Omicron: 927, Pi: 928, Rho: 929, Sigma: 931, Tau: 932, Upsilon: 933, Phi: 934, Chi: 935, Psi: 936, Omega: 937, alpha: 945, beta: 946, gamma: 947, delta: 948, epsilon: 949, zeta: 950, eta: 951, theta: 952, iota: 953, kappa: 954, lambda: 955, mu: 956, nu: 957, xi: 958, omicron: 959, pi: 960, rho: 961, sigmaf: 962, sigma: 963, tau: 964, upsilon: 965, phi: 966, chi: 967, psi: 968, omega: 969, thetasym: 977, upsih: 978, piv: 982, ensp: 8194, emsp: 8195, thinsp: 8201, zwnj: 8204, zwj: 8205, lrm: 8206, rlm: 8207, ndash: 8211, mdash: 8212, lsquo: 8216, rsquo: 8217, sbquo: 8218, ldquo: 8220, rdquo: 8221, bdquo: 8222, dagger: 8224, Dagger: 8225, bull: 8226, hellip: 8230, permil: 8240, prime: 8242, Prime: 8243, lsaquo: 8249, rsaquo: 8250, oline: 8254, frasl: 8260, euro: 8364, image: 8465, weierp: 8472, real: 8476, trade: 8482, alefsym: 8501, larr: 8592, uarr: 8593, rarr: 8594, darr: 8595, harr: 8596, crarr: 8629, lArr: 8656, uArr: 8657, rArr: 8658, dArr: 8659, hArr: 8660, forall: 8704, part: 8706, exist: 8707, empty: 8709, nabla: 8711, isin: 8712, notin: 8713, ni: 8715, prod: 8719, sum: 8721, minus: 8722, lowast: 8727, radic: 8730, prop: 8733, infin: 8734, ang: 8736, and: 8743, or: 8744, cap: 8745, cup: 8746, int: 8747, there4: 8756, sim: 8764, cong: 8773, asymp: 8776, ne: 8800, equiv: 8801, le: 8804, ge: 8805, sub: 8834, sup: 8835, nsub: 8836, sube: 8838, supe: 8839, oplus: 8853, otimes: 8855, perp: 8869, sdot: 8901, vellip: 8942, lceil: 8968, rceil: 8969, lfloor: 8970, rfloor: 8971, lang: 9001, rang: 9002, loz: 9674, spades: 9824, clubs: 9827, hearts: 9829, diams: 9830, }, };