Scripts linted

This commit is contained in:
Angelos Chalaris
2018-08-03 10:49:29 +03:00
parent 37da7ac424
commit d9593cdce5
13 changed files with 525 additions and 233 deletions

View File

@ -19,12 +19,19 @@ const unescapeHTML = str =>
'&': '&',
'&lt;': '<',
'&gt;': '>',
'&#39;': '\'',
'&#39;': "'",
'&quot;': '"'
}[tag] || tag)
);
if(util.isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE']) && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') {
console.log(`${chalk.green('NOBUILD')} website build terminated, parent commit is a Travis build!`);
if (
util.isTravisCI() &&
/^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE']) &&
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
) {
console.log(
`${chalk.green('NOBUILD')} website build terminated, parent commit is a Travis build!`
);
process.exit(0);
}
// Compile the mini.css framework and custom CSS styles, using `node-sass`.
@ -35,7 +42,7 @@ sass.render(
outFile: path.join('docs', 'mini.css'),
outputStyle: 'compressed'
},
function (err, result) {
function(err, result) {
if (!err) {
fs.writeFile(path.join('docs', 'mini.css'), result.css, function(err2) {
if (!err2) console.log(`${chalk.green('SUCCESS!')} mini.css file generated!`);
@ -54,7 +61,32 @@ const snippetsPath = './snippets',
// Set variables for script
let snippets = {},
archivedSnippets = {},
beginnerSnippetNames = ['everyNth', 'filterNonUnique', 'last', 'maxN', 'minN', 'nthElement', 'offset', 'sample', 'similarity', 'tail', 'currentURL', 'hasClass', 'getMeridiemSuffixOfInteger', 'factorial', 'fibonacci', 'gcd', 'isDivisible', 'isEven', 'isPrime', 'lcm', 'randomIntegerInRange', 'sum', 'reverseString', 'truncateString'],
beginnerSnippetNames = [
'everyNth',
'filterNonUnique',
'last',
'maxN',
'minN',
'nthElement',
'offset',
'sample',
'similarity',
'tail',
'currentURL',
'hasClass',
'getMeridiemSuffixOfInteger',
'factorial',
'fibonacci',
'gcd',
'isDivisible',
'isEven',
'isPrime',
'lcm',
'randomIntegerInRange',
'sum',
'reverseString',
'truncateString'
],
startPart = '',
endPart = '',
output = '',
@ -64,7 +96,6 @@ let snippets = {},
archivedStartPart = '',
archivedEndPart = '',
archivedOutput = '',
indexStaticFile = '',
pagesOutput = [],
tagDbData = {};
@ -74,16 +105,21 @@ console.time('Webber');
snippets = util.readSnippets(snippetsPath);
archivedSnippets = util.readSnippets(archivedSnippetsPath);
// Load static parts for all pages
try {
startPart = fs.readFileSync(path.join(staticPartsPath, 'page-start.html'), 'utf8');
endPart = fs.readFileSync(path.join(staticPartsPath, 'page-end.html'), 'utf8');
beginnerStartPart = fs.readFileSync(path.join(staticPartsPath, 'beginner-page-start.html'), 'utf8');
beginnerStartPart = fs.readFileSync(
path.join(staticPartsPath, 'beginner-page-start.html'),
'utf8'
);
beginnerEndPart = fs.readFileSync(path.join(staticPartsPath, 'beginner-page-end.html'), 'utf8');
archivedStartPart = fs.readFileSync(path.join(staticPartsPath, 'archived-page-start.html'), 'utf8');
archivedStartPart = fs.readFileSync(
path.join(staticPartsPath, 'archived-page-start.html'),
'utf8'
);
archivedEndPart = fs.readFileSync(path.join(staticPartsPath, 'archived-page-end.html'), 'utf8');
indexStaticFile = fs.readFileSync(path.join(staticPartsPath, 'index.html'), 'utf8');
@ -95,7 +131,11 @@ try {
// Load tag data from the database
tagDbData = util.readTags();
// Create the output for the index.html file (only locally or on Travis CRON or custom job)
if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api'))) {
if (
!util.isTravisCI() ||
(util.isTravisCI() &&
(process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api'))
) {
try {
// Shuffle the array of snippets, pick 3
let indexDailyPicks = '';
@ -110,68 +150,123 @@ if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE']
// Generate the html for the picked snippets
for (let snippet of Object.entries(dailyPicks))
indexDailyPicks +=
'<div class="card fluid pick">' +
'<div class="card fluid pick">' +
md
.render(`\n${snippets[snippet[0]]}`)
.replace(/<h3/g, `<h3 id="${snippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, `${snippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''}</h3>`)
.replace(
/<\/h3>/g,
`${snippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''}</h3>`
)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(
/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm,
(match, p1) =>
`<pre class="language-js">${Prism.highlight(
unescapeHTML(p1),
Prism.languages.javascript
)}</pre>`
)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy">&#128203;&nbsp;Copy to clipboard</button>' +
'</div></div>';
// Select the first snippet from today's picks
indexDailyPicks = indexDailyPicks.replace('card fluid pick', 'card fluid pick selected');
// Optimize punctuation nodes
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
indexDailyPicks = util.optimizeNodes(
indexDailyPicks,
/<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`
);
// Optimize operator nodes
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
indexDailyPicks = util.optimizeNodes(
indexDailyPicks,
/<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`
);
// Optimize keyword nodes
indexDailyPicks = util.optimizeNodes(indexDailyPicks, /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`);
indexDailyPicks = util.optimizeNodes(
indexDailyPicks,
/<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`
);
// Put the daily picks into the page
indexStaticFile = indexStaticFile.replace('$daily-picks', indexDailyPicks);
// Use the Github API to get the needed data
const githubApi = 'api.github.com';
const headers = util.isTravisCI()
? { 'User-Agent': '30-seconds-of-code', 'Authorization': 'token ' + process.env['GH_TOKEN']}
: { 'User-Agent': '30-seconds-of-code'};
? { 'User-Agent': '30-seconds-of-code', Authorization: 'token ' + process.env['GH_TOKEN'] }
: { 'User-Agent': '30-seconds-of-code' };
// Test the API's rate limit (keep for various reasons)
https.get({host: githubApi, path: '/rate_limit?', headers: headers}, res => {
res.on('data', function (chunk) {
https.get({ host: githubApi, path: '/rate_limit?', headers: headers }, res => {
res.on('data', function(chunk) {
console.log(`Remaining requests: ${JSON.parse(chunk).resources.core.remaining}`);
});
});
// Send requests and wait for responses, write to the page
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/commits?per_page=1', headers: headers}, resCommits => {
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/contributors?per_page=1', headers: headers}, resContributors => {
https.get({host: githubApi, path: '/repos/chalarangelo/30-seconds-of-code/stargazers?per_page=1', headers: headers}, resStars => {
let commits = resCommits.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g, ''),
contribs = resContributors.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g, ''),
stars = resStars.headers.link.split('&').slice(-1)[0].replace(/[^\d]/g, '');
indexStaticFile = indexStaticFile.replace(/\$snippet-count/g, Object.keys(snippets).length).replace(/\$commit-count/g, commits).replace(/\$contrib-count/g, contribs).replace(/\$star-count/g, stars);
indexStaticFile = minify(indexStaticFile, {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: false,
minifyCSS: true,
minifyJS: true,
keepClosingSlash: true,
processConditionalComments: true,
removeAttributeQuotes: false,
removeComments: true,
removeEmptyAttributes: false,
removeOptionalTags: false,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: false,
trimCustomFragments: true
});
// Generate 'index.html' file
fs.writeFileSync(path.join(docsPath, 'index.html'), indexStaticFile);
console.log(`${chalk.green('SUCCESS!')} index.html file generated!`);
});
});
});
https.get(
{
host: githubApi,
path: '/repos/chalarangelo/30-seconds-of-code/commits?per_page=1',
headers: headers
},
resCommits => {
https.get(
{
host: githubApi,
path: '/repos/chalarangelo/30-seconds-of-code/contributors?per_page=1',
headers: headers
},
resContributors => {
https.get(
{
host: githubApi,
path: '/repos/chalarangelo/30-seconds-of-code/stargazers?per_page=1',
headers: headers
},
resStars => {
let commits = resCommits.headers.link
.split('&')
.slice(-1)[0]
.replace(/[^\d]/g, ''),
contribs = resContributors.headers.link
.split('&')
.slice(-1)[0]
.replace(/[^\d]/g, ''),
stars = resStars.headers.link
.split('&')
.slice(-1)[0]
.replace(/[^\d]/g, '');
indexStaticFile = indexStaticFile
.replace(/\$snippet-count/g, Object.keys(snippets).length)
.replace(/\$commit-count/g, commits)
.replace(/\$contrib-count/g, contribs)
.replace(/\$star-count/g, stars);
indexStaticFile = minify(indexStaticFile, {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: false,
minifyCSS: true,
minifyJS: true,
keepClosingSlash: true,
processConditionalComments: true,
removeAttributeQuotes: false,
removeComments: true,
removeEmptyAttributes: false,
removeOptionalTags: false,
removeScriptTypeAttributes: false,
removeStyleLinkTypeAttributes: false,
trimCustomFragments: true
});
// Generate 'index.html' file
fs.writeFileSync(path.join(docsPath, 'index.html'), indexStaticFile);
console.log(`${chalk.green('SUCCESS!')} index.html file generated!`);
}
);
}
);
}
);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During index.html generation: ${err}`);
process.exit(1);
@ -185,13 +280,21 @@ try {
// Loop over tags and snippets to create the table of contents
for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1][0]))]
.filter(v => v)
.sort((a, b) => util.capitalize(a, true) === 'Uncategorized' ? 1 : util.capitalize(b, true) === 'Uncategorized' ? -1 : a.localeCompare(b))) {
output += '<h3>' +
md
.render(`${util.capitalize(tag, true)}\n`)
.replace(/<p>/g, '')
.replace(/<\/p>/g, '') +
'</h3>';
.sort(
(a, b) =>
util.capitalize(a, true) === 'Uncategorized'
? 1
: util.capitalize(b, true) === 'Uncategorized'
? -1
: a.localeCompare(b)
)) {
output +=
'<h3>' +
md
.render(`${util.capitalize(tag, true)}\n`)
.replace(/<p>/g, '')
.replace(/<\/p>/g, '') +
'</h3>';
for (let taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag))
output += md
.render(`[${taggedSnippet[0]}](./${tag}#${taggedSnippet[0].toLowerCase()})\n`)
@ -200,13 +303,23 @@ try {
.replace(/<a/g, `<a class="sublink-1" tags="${taggedSnippet[1].join(',')}"`);
output += '\n';
}
output += '</nav><main class="col-sm-12 col-md-8 col-lg-9" style="height: 100%;overflow-y: auto; background: #eceef2; padding: 0;">';
output +=
'</nav><main class="col-sm-12 col-md-8 col-lg-9" style="height: 100%;overflow-y: auto; background: #eceef2; padding: 0;">';
output += '<a id="top">&nbsp;</a>';
// Loop over tags and snippets to create the list of snippets
for (let tag of [...new Set(Object.entries(tagDbData).map(t => t[1][0]))]
.filter(v => v)
.sort((a, b) => util.capitalize(a, true) === 'Uncategorized' ? 1 : util.capitalize(b, true) === 'Uncategorized' ? -1 : a.localeCompare(b))) {
let localOutput = output.replace(/\$tag/g, util.capitalize(tag)).replace(new RegExp(`./${tag}#`, 'g'), '#');
.sort(
(a, b) =>
util.capitalize(a, true) === 'Uncategorized'
? 1
: util.capitalize(b, true) === 'Uncategorized'
? -1
: a.localeCompare(b)
)) {
let localOutput = output
.replace(/\$tag/g, util.capitalize(tag))
.replace(new RegExp(`./${tag}#`, 'g'), '#');
localOutput += md
.render(`## ${util.capitalize(tag, true)}\n`)
.replace(/<h2>/g, '<h2 style="text-align:center;">');
@ -215,22 +328,49 @@ try {
'<div class="card fluid">' +
md
.render(`\n${snippets[taggedSnippet[0] + '.md']}`)
.replace(/<h3/g, `<h3 id="${taggedSnippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, `${taggedSnippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''}</h3>`)
.replace(
/<h3/g,
`<h3 id="${taggedSnippet[0].toLowerCase()}" class="section double-padded"`
)
.replace(
/<\/h3>/g,
`${
taggedSnippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''
}</h3>`
)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(
/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm,
(match, p1) =>
`<pre class="language-js">${Prism.highlight(
unescapeHTML(p1),
Prism.languages.javascript
)}</pre>`
)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy">&#128203;&nbsp;Copy to clipboard</button>' +
'</div></div>';
// Add the ending static part
localOutput += `\n${endPart + '\n'}`;
// Optimize punctuation nodes
localOutput = util.optimizeNodes(localOutput, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
localOutput = util.optimizeNodes(
localOutput,
/<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`
);
// Optimize operator nodes
localOutput = util.optimizeNodes(localOutput, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
localOutput = util.optimizeNodes(
localOutput,
/<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`
);
// Optimize keyword nodes
localOutput = util.optimizeNodes(localOutput, /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`);
pagesOutput.push({'tag': tag, 'content': localOutput});
localOutput = util.optimizeNodes(
localOutput,
/<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`
);
pagesOutput.push({ tag: tag, content: localOutput });
}
// Minify output
pagesOutput.forEach(page => {
@ -250,7 +390,7 @@ try {
removeStyleLinkTypeAttributes: false,
trimCustomFragments: true
});
fs.writeFileSync(path.join(docsPath, page.tag+'.html'), page.content);
fs.writeFileSync(path.join(docsPath, page.tag + '.html'), page.content);
console.log(`${chalk.green('SUCCESS!')} ${page.tag}.html file generated!`);
});
} catch (err) {
@ -266,7 +406,7 @@ try {
// Filter begginer snippets
const filteredBeginnerSnippets = Object.keys(snippets)
.filter(key => beginnerSnippetNames.map(name => name+'.md').includes(key))
.filter(key => beginnerSnippetNames.map(name => name + '.md').includes(key))
.reduce((obj, key) => {
obj[key] = snippets[key];
return obj;
@ -274,26 +414,47 @@ try {
for (let snippet of Object.entries(filteredBeginnerSnippets))
beginnerOutput +=
'<div class="row">' +
'<div class="col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">' +
'<div class="row">' +
'<div class="col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">' +
'<div class="card fluid">' +
md
.render(`\n${snippets[snippet[0]]}`)
.replace(/<h3/g, `<h3 id="${snippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, `${snippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''}</h3>`)
.replace(
/<\/h3>/g,
`${snippet[1].includes('advanced') ? '<mark class="tag">advanced</mark>' : ''}</h3>`
)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(
/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm,
(match, p1) =>
`<pre class="language-js">${Prism.highlight(
unescapeHTML(p1),
Prism.languages.javascript
)}</pre>`
)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy">&#128203;&nbsp;Copy to clipboard</button>' +
'</div></div></div></div>';
// Optimize punctuation nodes
beginnerOutput = util.optimizeNodes(beginnerOutput, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
// Optimize operator nodes
beginnerOutput = util.optimizeNodes(beginnerOutput, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
// Optimize keyword nodes
beginnerOutput = util.optimizeNodes(beginnerOutput, /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`);
// Optimize punctuation nodes
beginnerOutput = util.optimizeNodes(
beginnerOutput,
/<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`
);
// Optimize operator nodes
beginnerOutput = util.optimizeNodes(
beginnerOutput,
/<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`
);
// Optimize keyword nodes
beginnerOutput = util.optimizeNodes(
beginnerOutput,
/<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`
);
beginnerOutput += `${beginnerEndPart}`;
@ -316,7 +477,6 @@ try {
});
fs.writeFileSync(path.join(docsPath, 'beginner.html'), minifiedBeginnerOutput);
console.log(`${chalk.green('SUCCESS!')} beginner.html file generated!`);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During beginner.html generation: ${err}`);
process.exit(1);
@ -334,32 +494,51 @@ try {
.filter(key => !excludeFiles.includes(key))
.reduce((obj, key) => {
obj[key] = archivedSnippets[key];
return obj;
}, {});
return obj;
}, {});
// Generate archived snippets from md files
for (let snippet of Object.entries(filteredArchivedSnippets))
archivedOutput +=
'<div class="row">' +
'<div class="col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">' +
'<div class="row">' +
'<div class="col-sm-12 col-md-10 col-lg-8 col-md-offset-1 col-lg-offset-2">' +
'<div class="card fluid">' +
md
.render(`\n${filteredArchivedSnippets[snippet[0]]}`)
.replace(/<h3/g, `<h3 id="${snippet[0].toLowerCase()}" class="section double-padded"`)
.replace(/<\/h3>/g, '</h3><div class="section double-padded">')
.replace(/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm, (match, p1) => `<pre class="language-js">${Prism.highlight(unescapeHTML(p1), Prism.languages.javascript)}</pre>`)
.replace(
/<pre><code class="language-js">([^\0]*?)<\/code><\/pre>/gm,
(match, p1) =>
`<pre class="language-js">${Prism.highlight(
unescapeHTML(p1),
Prism.languages.javascript
)}</pre>`
)
.replace(/<\/pre>\s+<pre/g, '</pre><label class="collapse">Show examples</label><pre') +
'<button class="primary clipboard-copy">&#128203;&nbsp;Copy to clipboard</button>' +
'</div></div></div></div>';
// Optimize punctuation nodes
archivedOutput = util.optimizeNodes(archivedOutput, /<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`);
// Optimize operator nodes
archivedOutput = util.optimizeNodes(archivedOutput, /<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`);
// Optimize keyword nodes
archivedOutput = util.optimizeNodes(archivedOutput, /<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm, (match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`);
// Optimize punctuation nodes
archivedOutput = util.optimizeNodes(
archivedOutput,
/<span class="token punctuation">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token punctuation">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token punctuation">${p1}${p2}${p3}</span>`
);
// Optimize operator nodes
archivedOutput = util.optimizeNodes(
archivedOutput,
/<span class="token operator">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token operator">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token operator">${p1}${p2}${p3}</span>`
);
// Optimize keyword nodes
archivedOutput = util.optimizeNodes(
archivedOutput,
/<span class="token keyword">([^\0<]*?)<\/span>([\n\r\s]*)<span class="token keyword">([^\0]*?)<\/span>/gm,
(match, p1, p2, p3) => `<span class="token keyword">${p1}${p2}${p3}</span>`
);
archivedOutput += `${archivedEndPart}`;
archivedOutput += `${archivedEndPart}`;
// Generate and minify 'archive.html' file
const minifiedArchivedOutput = minify(archivedOutput, {
@ -381,7 +560,6 @@ try {
fs.writeFileSync(path.join(docsPath, 'archive.html'), minifiedArchivedOutput);
console.log(`${chalk.green('SUCCESS!')} archive.html file generated!`);
} catch (err) {
console.log(`${chalk.red('ERROR!')} During archive.html generation: ${err}`);
process.exit(1);