1var nbv = (function() { 2 "use strict"; 3 4 var d = document; 5 var st = {}; // settings 6 7 function render_ipynb(obj, target, settings) { 8 if (!window.marked || !window.Prism) { 9 console.error('expecting libraries marked.js and Prism.js to be present'); 10 return; 11 } 12 st = settings || {}; 13 14 st.nbformat = obj.nbformat; 15 if (st.nbformat < 3) { 16 console.error('Format of the notebook too old'); 17 return; 18 } 19 20 if (st.nbformat > 3) 21 st.lang = obj.metadata.kernelspec.language; 22 23 // wipe all inner elements of our target 24 while (target.firstChild) { 25 target.removeChild(target.firstChild); 26 } 27 var t = d.createElement('div'); 28 t.setAttribute('style', [ 29 'max-width: 960px', 30 'border: 1px solid #ccc', 31 'margin: 1em auto', 32 'padding: 1.5em 1.5em 1.5em 7em', 33 'background-color: white', 34 'box-shadow: 0 0 10px #ccc' 35 ].join(';')); 36 target.appendChild(t); 37 st.target = t; 38 39 // v4 has cells directly in the object, v3 had a list of 40 // worksheets, each with a list of cells 41 var cells = obj.cells || function() { 42 var ret = []; 43 for (var j=0; j < obj.worksheets.length; j++) { 44 ret = ret.concat(obj.worksheets[j].cells); 45 } 46 return ret; 47 }(); 48 49 for (var j=0; j < cells.length; j++) { 50 var tc = cells[j]; 51 52 var cell = d.createElement('div'); 53 cell.setAttribute('style', 'padding-bottom: .5em;'); 54 55 var dm = d.createElement('div'); // empty div as a fallback 56 57 switch (tc.cell_type) { 58 case 'code': 59 dm = handle_code(tc); 60 break; 61 case 'markdown': 62 dm = handle_mdown(tc); 63 break; 64 65 default: 66 console.error('Unsupported cell type: ' + tc.cell_type); 67 } 68 cell.appendChild(dm); 69 t.appendChild(cell); 70 } 71 72 // if (st.toc) 73 // render_toc() 74 } 75 76 function excount(cell, tin) { 77 var cc = d.createElement('span'); 78 cc.setAttribute('style', [ 79 'display: block', 80 'position: absolute', 81 'top: ' + (tin ? '5px' : '0 !important'), 82 'left: -7.5em', 83 'width: 7em', 84 'font-family: monospace', 85 'text-align: right', 86 'color: ' + (tin ? '#303fba' : '#de4815') 87 ].join(';')); 88 cc.textContent = (tin ? 'In': 'Out') + ' [' + 89 ((!cell.execution_count && !cell.prompt_number) ? ' ' : 90 (cell.execution_count || cell.prompt_number)) + ']:'; 91 return cc; 92 } 93 94 // receives cell, outputs DOM 95 function handle_code(cell) { 96 var el = d.createElement('div'); // container for it all 97 el.style.position = 'relative'; // for excount positioning 98 99 el.appendChild(excount(cell, true)); 100 101 var pre = d.createElement('pre'); 102 // because code may also be within markdown: 103 pre.setAttribute('style', [ 104 'background: #f7f7f7', 105 'border: 1px solid #cfcfcf', 106 'padding: .4em', 107 'margin-bottom: 0', 108 'margin-top: 0', 109 'border-radius: 2px', 110 'overflow-x: scroll', 111 'min-height: .85em' 112 ].join(';')); 113 var code = d.createElement('code'); 114 115 // if (st.hasOwnProperty('lang')) 116 code.setAttribute('class', 'language-' + st.lang || cell.language); 117 118 // no need to join on '\n' - newlines are in the code already 119 // .source for v4, .input for v3 120 code.textContent = (cell.source || cell.input).join(''); 121 122 pre.appendChild(code); 123 el.appendChild(pre); 124 Prism.highlightElement(code); 125 126 // outputs now 127 var outp = d.createElement('div'); 128 outp.style.margin = '1em 0 .5em 0'; 129 130 for (var j=0; j < cell.outputs.length; j++) { 131 var dm = d.createElement('div'); // wrapper 132 dm.style.position = 'relative'; // for excount positioning 133 var dt = cell.outputs[j]; 134 if (dt.output_type == 'execute_result') 135 dm.appendChild(excount(dt, false)); 136 137 switch (dt.output_type) { 138 case 'execute_result': 139 dm.appendChild(handle_cell_output(dt)); 140 break; 141 case 'stream': 142 dm.appendChild(handle_stream_output(dt)); 143 break; 144 case 'display_data': 145 if (st.nbformat > 3) { 146 dm.appendChild(handle_cell_output(dt)); 147 break; 148 } 149 // if 3, fall through to pyout 150 case 'pyout': 151 // legacy (v3) 152 dm.appendChild(handle_pyout(dt)); 153 break; 154 default: 155 console.error('Not supported output_type: ' + 156 cell.outputs[j].output_type); 157 } 158 159 outp.appendChild(dm); 160 } 161 el.appendChild(outp); 162 163 return el; 164 } 165 166 function handle_cell_output(dt) { 167 var el = d.createElement('div'); 168 el.style.minHeight = '1em'; 169 170 // individual outputs 171 var fmts = Object.keys(dt.data); 172 for (var j=0; j < fmts.length; j++) { 173 var fmt = fmts[j]; 174 var dm = d.createElement('div'); 175 switch (fmt) { 176 case 'text/plain': 177 // text/plain might be just a fallback here 178 // fixed #10 179 if (fmts.includes('text/html')) continue; 180 181 dm = d.createElement('pre'); 182 dm.style.margin = 0; 183 dm.textContent = dt.data[fmt].join(''); 184 break; 185 186 case 'text/html': 187 dm.style.overflow = 'scroll'; 188 dm.innerHTML = dt.data[fmt].join(''); 189 190 // we may have generated some HTML tables we need to style 191 var dfs = dm.getElementsByClassName('dataframe'); 192 for (var k=0; k < dfs.length; k++) { 193 dfs[k].setAttribute('style', [ 194 'border-collapse: collapse', 195 'text-align: left' 196 // 'margin-top: 1em' 197 ].join(';')); 198 199 // let's style individual cells as well 200 var cl = dfs[k].querySelectorAll('td, th'); 201 for (var l=0; l < cl.length; l++) { 202 cl[l].style.padding = '3px'; 203 } 204 205 } 206 207 break; 208 209 default: 210 if (fmt.startsWith('image/')) { 211 dm = d.createElement('img'); 212 dm.setAttribute('src', 'data:' + fmt + ';base64,' + dt.data[fmt]); 213 break; 214 } 215 console.error('unexpected format: ' + fmt); 216 } 217 el.appendChild(dm); 218 219 } 220 221 return el; 222 } 223 224 function handle_stream_output(dt) { 225 // name in v4, stream in v3 226 if ( (dt.name || dt.stream) != 'stdout' || dt.output_type != 'stream') 227 console.error('unexpected stream spec'); 228 229 if (!dt.hasOwnProperty('text')) 230 console.error('data for stream missing'); 231 232 var cn = d.createElement('pre'); 233 cn.textContent = dt.text.join(''); 234 235 return cn; 236 } 237 238 function handle_mdown(cell) { 239 var el = d.createElement('div'); 240 el.innerHTML = marked(cell.source.join('')); 241 242 return el; 243 } 244 245 // handling legacy notebooks (v3) 246 function handle_pyout(cell) { 247 var el = d.createElement('div'); 248 249 if (cell.hasOwnProperty('prompt_number')) 250 el.appendChild(excount(cell, false)); 251 252 // var ks = Object.keys(cell) 253 // text, png, jpeg, html -- supported 254 // svg, latex, javascript, json, pdf, metadata -- not yet 255 Object.keys(cell).forEach(function(k) { 256 if (['output_type', 'prompt_number'].indexOf(k) > -1) 257 return; 258 var p = d.createElement('span'); // if errs 259 switch (k) { 260 case 'text': 261 p = d.createElement('pre'); 262 p.style.margin = 0; 263 p.textContent = cell[k].join(''); 264 break; 265 case 'html': 266 p = d.createElement('div'); 267 // guessing here, haven't seen a v3 HTML element 268 p.innerHTML = cell[k].join(''); 269 break; 270 case 'png': 271 case 'jpeg': 272 p = d.createElement('img'); 273 p.setAttribute('src', 'data:' + k + ';base64,' + cell[k]); 274 275 break; 276 277 default: 278 console.error('unsupported pyout format: ' + k); 279 } 280 el.appendChild(p); 281 }); 282 283 return el; 284 } 285 286 function sanitise(el) { 287 return el.toLowerCase().replace(/\W+/g, '-'); 288 } 289 290 // function render_toc() { 291 // var els = st.target.querySelector('h1,h2,h3,h4,h5,h6') 292 // var minl = 6 293 // for (var j=0; j<els.length;j++) { 294 // minl = (els[j].nodeName[1] < minl) ? 295 // parseInt(els[j].nodeName[1]) : minl 296 // } 297 // console.log(minl) 298 299 // } 300 301 302 return { 303 render: render_ipynb 304 }; 305 306})();
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.