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