1#!/usr/bin/env node 2 3const fs = require('fs'); 4const cheerio = require('cheerio'); 5const hljs = require('./build/highlight.js'); 6const Entities = require('html-entities').AllHtmlEntities; 7const entities = new Entities(); 8 9const githublink = `\ 10<li class="part-title">\ 11<a href="https://github.com/dtolnay/cxx">\ 12<i class="fa fa-github"></i>\ 13https://github.com/dtolnay/cxx\ 14</a>\ 15</li>`; 16 17const opengraph = `\ 18<meta property="og:image" content="https://cxx.rs/cxx.png" />\ 19<meta property="og:site_name" content="CXX" />\ 20<meta property="og:title" content="CXX — safe interop between Rust and C++" />\ 21<meta name="twitter:image:src" content="https://cxx.rs/cxx.png" />\ 22<meta name="twitter:site" content="@davidtolnay" />\ 23<meta name="twitter:card" content="summary" />\ 24<meta name="twitter:title" content="CXX — safe interop between Rust and C++" />`; 25 26const htmljs = `\ 27var html = document.querySelector('html'); 28html.classList.remove('no-js'); 29html.classList.add('js');`; 30 31const dirs = ['build']; 32while (dirs.length) { 33 const dir = dirs.pop(); 34 fs.readdirSync(dir).forEach((entry) => { 35 path = dir + '/' + entry; 36 const stat = fs.statSync(path); 37 if (stat.isDirectory()) { 38 dirs.push(path); 39 return; 40 } 41 42 if (!path.endsWith('.html')) { 43 return; 44 } 45 46 const index = fs.readFileSync(path, 'utf8'); 47 const $ = cheerio.load(index, { decodeEntities: false }); 48 49 $('head').append(opengraph); 50 $('script:nth-of-type(3)').text(htmljs); 51 $('nav#sidebar ol.chapter').append(githublink); 52 $('head link[href="tomorrow-night.css"]').attr('disabled', true); 53 $('head link[href="ayu-highlight.css"]').attr('disabled', true); 54 $('button#theme-toggle').attr('style', 'display:none'); 55 $('pre code').each(function () { 56 const node = $(this); 57 const langClass = node.attr('class').split(' ', 2)[0]; 58 if (!langClass.startsWith('language-')) { 59 return; 60 } 61 const lang = langClass.replace('language-', ''); 62 const lines = node.html().split('\n'); 63 const boring = lines.map((line) => 64 line.includes('<span class="boring">') 65 ); 66 const ellipsis = lines.map((line) => line.includes('// ...')); 67 const target = entities.decode(node.text()); 68 const highlighted = hljs.highlight(lang, target).value; 69 const result = highlighted 70 .split('\n') 71 .map(function (line, i) { 72 if (boring[i]) { 73 line = '<span class="boring">' + line; 74 } else if (ellipsis[i]) { 75 line = '<span class="ellipsis">' + line; 76 } 77 if (i > 0 && (boring[i - 1] || ellipsis[i - 1])) { 78 line = '</span>' + line; 79 } 80 return line; 81 }) 82 .join('\n'); 83 node.text(result); 84 node.removeClass(langClass); 85 if (!node.hasClass('focuscomment')) { 86 node.addClass('hidelines'); 87 node.addClass('hide-boring'); 88 } 89 }); 90 $('code').each(function () { 91 $(this).addClass('hljs'); 92 }); 93 94 const out = $.html(); 95 fs.writeFileSync(path, out); 96 }); 97} 98 99fs.copyFileSync('build/highlight.css', 'build/tomorrow-night.css'); 100fs.copyFileSync('build/highlight.css', 'build/ayu-highlight.css'); 101 102var bookjs = fs.readFileSync('build/book.js', 'utf8'); 103bookjs = bookjs.replace('set_theme(theme, false);', ''); 104fs.writeFileSync('build/book.js', bookjs); 105