1(function () { 2 3 if (typeof Prism === 'undefined' || typeof document === 'undefined') { 4 return; 5 } 6 7 var CLASS_PATTERN = /(?:^|\s)command-line(?:\s|$)/; 8 var PROMPT_CLASS = 'command-line-prompt'; 9 10 /** @type {(str: string, prefix: string) => boolean} */ 11 var startsWith = ''.startsWith 12 ? function (s, p) { return s.startsWith(p); } 13 : function (s, p) { return s.indexOf(p) === 0; }; 14 15 // Support for IE11 that has no endsWith() 16 /** @type {(str: string, suffix: string) => boolean} */ 17 var endsWith = ''.endsWith 18 ? function (str, suffix) { 19 return str.endsWith(suffix); 20 } 21 : function (str, suffix) { 22 var len = str.length; 23 return str.substring(len - suffix.length, len) === suffix; 24 }; 25 26 /** 27 * Returns whether the given hook environment has a command line info object. 28 * 29 * @param {any} env 30 * @returns {boolean} 31 */ 32 function hasCommandLineInfo(env) { 33 var vars = env.vars = env.vars || {}; 34 return 'command-line' in vars; 35 } 36 /** 37 * Returns the command line info object from the given hook environment. 38 * 39 * @param {any} env 40 * @returns {CommandLineInfo} 41 * 42 * @typedef CommandLineInfo 43 * @property {boolean} [complete] 44 * @property {number} [numberOfLines] 45 * @property {string[]} [outputLines] 46 */ 47 function getCommandLineInfo(env) { 48 var vars = env.vars = env.vars || {}; 49 return vars['command-line'] = vars['command-line'] || {}; 50 } 51 52 53 Prism.hooks.add('before-highlight', function (env) { 54 var commandLine = getCommandLineInfo(env); 55 56 if (commandLine.complete || !env.code) { 57 commandLine.complete = true; 58 return; 59 } 60 61 // Works only for <code> wrapped inside <pre> (not inline). 62 var pre = env.element.parentElement; 63 if (!pre || !/pre/i.test(pre.nodeName) || // Abort only if neither the <pre> nor the <code> have the class 64 (!CLASS_PATTERN.test(pre.className) && !CLASS_PATTERN.test(env.element.className))) { 65 commandLine.complete = true; 66 return; 67 } 68 69 // The element might be highlighted multiple times, so we just remove the previous prompt 70 var existingPrompt = env.element.querySelector('.' + PROMPT_CLASS); 71 if (existingPrompt) { 72 existingPrompt.remove(); 73 } 74 75 var codeLines = env.code.split('\n'); 76 77 var continuationLineIndicies = commandLine.continuationLineIndicies = new Set(); 78 var lineContinuationStr = pre.getAttribute('data-continuation-str'); 79 80 // Identify code lines that are a continuation line and thus don't need 81 // a prompt 82 if (lineContinuationStr && codeLines.length > 1) { 83 for (var j = 1; j < codeLines.length; j++) { 84 if (codeLines.hasOwnProperty(j - 1) 85 && endsWith(codeLines[j - 1], lineContinuationStr)) { 86 // Mark this line as being a continuation line 87 continuationLineIndicies.add(j); 88 } 89 } 90 } 91 92 commandLine.numberOfLines = codeLines.length; 93 /** @type {string[]} */ 94 var outputLines = commandLine.outputLines = []; 95 96 var outputSections = pre.getAttribute('data-output'); 97 var outputFilter = pre.getAttribute('data-filter-output'); 98 if (outputSections !== null) { // The user specified the output lines. -- cwells 99 outputSections.split(',').forEach(function (section) { 100 var range = section.split('-'); 101 var outputStart = parseInt(range[0], 10); 102 var outputEnd = range.length === 2 ? parseInt(range[1], 10) : outputStart; 103 104 if (!isNaN(outputStart) && !isNaN(outputEnd)) { 105 if (outputStart < 1) { 106 outputStart = 1; 107 } 108 if (outputEnd > codeLines.length) { 109 outputEnd = codeLines.length; 110 } 111 // Convert start and end to 0-based to simplify the arrays. -- cwells 112 outputStart--; 113 outputEnd--; 114 // Save the output line in an array and clear it in the code so it's not highlighted. -- cwells 115 for (var j = outputStart; j <= outputEnd; j++) { 116 outputLines[j] = codeLines[j]; 117 codeLines[j] = ''; 118 } 119 } 120 }); 121 } else if (outputFilter) { // Treat lines beginning with this string as output. -- cwells 122 for (var i = 0; i < codeLines.length; i++) { 123 if (startsWith(codeLines[i], outputFilter)) { // This line is output. -- cwells 124 outputLines[i] = codeLines[i].slice(outputFilter.length); 125 codeLines[i] = ''; 126 } 127 } 128 } 129 130 env.code = codeLines.join('\n'); 131 }); 132 133 Prism.hooks.add('before-insert', function (env) { 134 var commandLine = getCommandLineInfo(env); 135 136 if (commandLine.complete) { 137 return; 138 } 139 140 // Reinsert the output lines into the highlighted code. -- cwells 141 var codeLines = env.highlightedCode.split('\n'); 142 var outputLines = commandLine.outputLines || []; 143 for (var i = 0, l = codeLines.length; i < l; i++) { 144 // Add spans to allow distinction of input/output text for styling 145 if (outputLines.hasOwnProperty(i)) { 146 // outputLines were removed from codeLines so missed out on escaping 147 // of markup so do it here. 148 codeLines[i] = '<span class="token output">' 149 + Prism.util.encode(outputLines[i]) + '</span>'; 150 } else { 151 codeLines[i] = '<span class="token command">' 152 + codeLines[i] + '</span>'; 153 } 154 } 155 env.highlightedCode = codeLines.join('\n'); 156 }); 157 158 Prism.hooks.add('complete', function (env) { 159 if (!hasCommandLineInfo(env)) { 160 // the previous hooks never ran 161 return; 162 } 163 164 var commandLine = getCommandLineInfo(env); 165 166 if (commandLine.complete) { 167 return; 168 } 169 170 var pre = env.element.parentElement; 171 if (CLASS_PATTERN.test(env.element.className)) { // Remove the class "command-line" from the <code> 172 env.element.className = env.element.className.replace(CLASS_PATTERN, ' '); 173 } 174 if (!CLASS_PATTERN.test(pre.className)) { // Add the class "command-line" to the <pre> 175 pre.className += ' command-line'; 176 } 177 178 function getAttribute(key, defaultValue) { 179 return (pre.getAttribute(key) || defaultValue).replace(/"/g, '"'); 180 } 181 182 // Create the "rows" that will become the command-line prompts. -- cwells 183 var promptLines = ''; 184 var rowCount = commandLine.numberOfLines || 0; 185 var promptText = getAttribute('data-prompt', ''); 186 var promptLine; 187 if (promptText !== '') { 188 promptLine = '<span data-prompt="' + promptText + '"></span>'; 189 } else { 190 var user = getAttribute('data-user', 'user'); 191 var host = getAttribute('data-host', 'localhost'); 192 promptLine = '<span data-user="' + user + '" data-host="' + host
192+ '"></span>'; 193 } 194 195 var continuationLineIndicies = commandLine.continuationLineIndicies || new Set(); 196 var continuationPromptText = getAttribute('data-continuation-prompt', '>'); 197 var continuationPromptLine = '<span data-continuation-prompt="' + continuationPromptText + '"></span>'; 198 199 // Assemble all the appropriate prompt/continuation lines 200 for (var j = 0; j < rowCount; j++) { 201 if (continuationLineIndicies.has(j)) { 202 promptLines += continuationPromptLine; 203 } else { 204 promptLines += promptLine; 205 } 206 } 207 208 // Create the wrapper element. -- cwells 209 var prompt = document.createElement('span'); 210 prompt.className = PROMPT_CLASS; 211 prompt.innerHTML = promptLines; 212 213 // Remove the prompt from the output lines. -- cwells 214 var outputLines = commandLine.outputLines || []; 215 for (var i = 0, l = outputLines.length; i < l; i++) { 216 if (outputLines.hasOwnProperty(i)) { 217 var node = prompt.children[i]; 218 node.removeAttribute('data-user'); 219 node.removeAttribute('data-host'); 220 node.removeAttribute('data-prompt'); 221 } 222 } 223 224 env.element.insertBefore(prompt, env.element.firstChild); 225 commandLine.complete = true; 226 }); 227 228}());
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.