Scripts linted
This commit is contained in:
@ -14,8 +14,13 @@ let snippetsArchiveData = require('../snippet_data/snippetsArchive.json');
|
||||
const OUTPUT_PATH = './snippet_data';
|
||||
console.time('Analyzer');
|
||||
// Read data
|
||||
let snippetTokens = {data: snippetsData.data.map(snippet => {
|
||||
let tokens = prism.tokenize(snippet.attributes.codeBlocks[0], prism.languages.javascript, 'javascript');
|
||||
let snippetTokens = {
|
||||
data: snippetsData.data.map(snippet => {
|
||||
let tokens = prism.tokenize(
|
||||
snippet.attributes.codeBlocks[0],
|
||||
prism.languages.javascript,
|
||||
'javascript'
|
||||
);
|
||||
return {
|
||||
id: snippet.id,
|
||||
type: 'snippetAnalysis',
|
||||
@ -25,15 +30,24 @@ let snippetTokens = {data: snippetsData.data.map(snippet => {
|
||||
functionCount: tokens.filter(t => t.type === 'function').length,
|
||||
operatorCount: tokens.filter(t => t.type === 'operator').length,
|
||||
keywordCount: tokens.filter(t => t.type === 'keyword').length,
|
||||
distinctFunctionCount: [...new Set(tokens.filter(t => t.type === 'function').map(t => t.content))].length
|
||||
distinctFunctionCount: [
|
||||
...new Set(tokens.filter(t => t.type === 'function').map(t => t.content))
|
||||
].length
|
||||
},
|
||||
meta: {
|
||||
hash: snippet.meta.hash
|
||||
}
|
||||
};
|
||||
}), meta: { specification: "http://jsonapi.org/format/"}};
|
||||
let snippetArchiveTokens = {data: snippetsArchiveData.data.map(snippet => {
|
||||
let tokens = prism.tokenize(snippet.attributes.codeBlocks[0], prism.languages.javascript, 'javascript');
|
||||
}),
|
||||
meta: { specification: 'http://jsonapi.org/format/' }
|
||||
};
|
||||
let snippetArchiveTokens = {
|
||||
data: snippetsArchiveData.data.map(snippet => {
|
||||
let tokens = prism.tokenize(
|
||||
snippet.attributes.codeBlocks[0],
|
||||
prism.languages.javascript,
|
||||
'javascript'
|
||||
);
|
||||
return {
|
||||
id: snippet.id,
|
||||
type: 'snippetAnalysis',
|
||||
@ -43,16 +57,30 @@ let snippetArchiveTokens = {data: snippetsArchiveData.data.map(snippet => {
|
||||
functionCount: tokens.filter(t => t.type === 'function').length,
|
||||
operatorCount: tokens.filter(t => t.type === 'operator').length,
|
||||
keywordCount: tokens.filter(t => t.type === 'keyword').length,
|
||||
distinctFunctionCount: [...new Set(tokens.filter(t => t.type === 'function').map(t => t.content))].length
|
||||
distinctFunctionCount: [
|
||||
...new Set(tokens.filter(t => t.type === 'function').map(t => t.content))
|
||||
].length
|
||||
},
|
||||
meta: {
|
||||
hash: snippet.meta.hash
|
||||
}
|
||||
};
|
||||
}), meta: { specification: "http://jsonapi.org/format/"}};
|
||||
}),
|
||||
meta: { specification: 'http://jsonapi.org/format/' }
|
||||
};
|
||||
// Write data
|
||||
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippetAnalytics.json'), JSON.stringify(snippetTokens, null, 2));
|
||||
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippetArchiveAnalytics.json'), JSON.stringify(snippetArchiveTokens, null, 2));
|
||||
fs.writeFileSync(
|
||||
path.join(OUTPUT_PATH, 'snippetAnalytics.json'),
|
||||
JSON.stringify(snippetTokens, null, 2)
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(OUTPUT_PATH, 'snippetArchiveAnalytics.json'),
|
||||
JSON.stringify(snippetArchiveTokens, null, 2)
|
||||
);
|
||||
// Display messages and time
|
||||
console.log(`${chalk.green('SUCCESS!')} snippetAnalyticss.json and snippetArchiveAnalytics.json files generated!`);
|
||||
console.log(
|
||||
`${chalk.green(
|
||||
'SUCCESS!'
|
||||
)} snippetAnalyticss.json and snippetArchiveAnalytics.json files generated!`
|
||||
);
|
||||
console.timeEnd('Analyzer');
|
||||
|
||||
@ -12,10 +12,15 @@ const SNIPPETS_PATH = './snippets';
|
||||
const SNIPPETS_ARCHIVE_PATH = './snippets_archive';
|
||||
const STATIC_PARTS_PATH = './static-parts';
|
||||
if (util.isTravisCI() && /^Travis build: \d+/g.test(process.env['TRAVIS_COMMIT_MESSAGE'])) {
|
||||
console.log(`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`);
|
||||
console.log(
|
||||
`${chalk.green('NOBUILD')} README build terminated, parent commit is a Travis build!`
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
if (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api')) {
|
||||
if (
|
||||
util.isTravisCI() &&
|
||||
(process.env['TRAVIS_EVENT_TYPE'] === 'cron' || process.env['TRAVIS_EVENT_TYPE'] === 'api')
|
||||
) {
|
||||
console.log(`${chalk.green('ARCHIVE')} Cron job or custom build, building archive README!`);
|
||||
console.time('Builder');
|
||||
let snippets = {};
|
||||
@ -113,7 +118,15 @@ try {
|
||||
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)))
|
||||
.sort(
|
||||
(a, b) =>
|
||||
util.capitalize(a, true) === 'Uncategorized'
|
||||
? 1
|
||||
: util.capitalize(b, true) === 'Uncategorized'
|
||||
? -1
|
||||
: a.localeCompare(b)
|
||||
)
|
||||
)
|
||||
];
|
||||
|
||||
console.log(tags);
|
||||
@ -124,11 +137,12 @@ try {
|
||||
// Loop over tags and snippets to create the table of contents
|
||||
for (const tag of tags) {
|
||||
const capitalizedTag = util.capitalize(tag, true);
|
||||
output += `### ${
|
||||
EMOJIS[tag] || ''
|
||||
} ${capitalizedTag}\n\n<details>\n<summary>View contents</summary>\n\n`;
|
||||
output += `### ${EMOJIS[tag] ||
|
||||
''} ${capitalizedTag}\n\n<details>\n<summary>View contents</summary>\n\n`;
|
||||
for (const taggedSnippet of Object.entries(tagDbData).filter(v => v[1][0] === tag)) {
|
||||
output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${taggedSnippet[1].includes('advanced')?'-':''})\n`;
|
||||
output += `* [\`${taggedSnippet[0]}\`](#${taggedSnippet[0].toLowerCase()}${
|
||||
taggedSnippet[1].includes('advanced') ? '-' : ''
|
||||
})\n`;
|
||||
}
|
||||
output += '\n</details>\n\n';
|
||||
}
|
||||
|
||||
@ -12,12 +12,18 @@ const SNIPPETS_PATH = './snippets';
|
||||
const SNIPPETS_ARCHIVE_PATH = './snippets_archive';
|
||||
const OUTPUT_PATH = './snippet_data';
|
||||
// Check if running on Travis - only build for cron jobs and custom builds
|
||||
if(util.isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') {
|
||||
if (
|
||||
util.isTravisCI() &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
|
||||
) {
|
||||
console.log(`${chalk.green('NOBUILD')} snippet extraction terminated, not a cron or api build!`);
|
||||
process.exit(0);
|
||||
}
|
||||
// Read data
|
||||
let snippets = {}, archivedSnippets = {}, tagDbData = {};
|
||||
let snippets = {},
|
||||
archivedSnippets = {},
|
||||
tagDbData = {};
|
||||
console.time('Extractor');
|
||||
snippets = util.readSnippets(SNIPPETS_PATH);
|
||||
archivedSnippets = util.readSnippets(SNIPPETS_ARCHIVE_PATH);
|
||||
@ -31,7 +37,9 @@ let snippetData = {
|
||||
attributes: {
|
||||
fileName: key,
|
||||
text: util.getTextualContent(snippets[key]).trim(),
|
||||
codeBlocks: util.getCodeBlocks(snippets[key]).map(v => v.replace(/```js([\s\S]*?)```/g, '$1').trim()),
|
||||
codeBlocks: util
|
||||
.getCodeBlocks(snippets[key])
|
||||
.map(v => v.replace(/```js([\s\S]*?)```/g, '$1').trim()),
|
||||
tags: tagDbData[key.slice(0, -3)]
|
||||
},
|
||||
meta: {
|
||||
@ -53,7 +61,9 @@ let snippetArchiveData = {
|
||||
attributes: {
|
||||
fileName: key,
|
||||
text: util.getTextualContent(archivedSnippets[key]).trim(),
|
||||
codeBlocks: util.getCodeBlocks(archivedSnippets[key]).map(v => v.replace(/```js([\s\S]*?)```/g, '$1').trim()),
|
||||
codeBlocks: util
|
||||
.getCodeBlocks(archivedSnippets[key])
|
||||
.map(v => v.replace(/```js([\s\S]*?)```/g, '$1').trim()),
|
||||
tags: []
|
||||
},
|
||||
meta: {
|
||||
@ -68,7 +78,10 @@ let snippetArchiveData = {
|
||||
};
|
||||
// Write files
|
||||
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippets.json'), JSON.stringify(snippetData, null, 2));
|
||||
fs.writeFileSync(path.join(OUTPUT_PATH, 'snippetsArchive.json'), JSON.stringify(snippetArchiveData, null, 2));
|
||||
fs.writeFileSync(
|
||||
path.join(OUTPUT_PATH, 'snippetsArchive.json'),
|
||||
JSON.stringify(snippetArchiveData, null, 2)
|
||||
);
|
||||
// Display messages and time
|
||||
console.log(`${chalk.green('SUCCESS!')} snippets.json and snippetsArchive.json files generated!`);
|
||||
console.timeEnd('Extractor');
|
||||
|
||||
@ -10,10 +10,13 @@ const util = require('../util');
|
||||
const glossaryFiles = util.getFilesInDir('./glossary', false);
|
||||
|
||||
try {
|
||||
const output = glossaryFiles.reduce(
|
||||
const output =
|
||||
glossaryFiles.reduce(
|
||||
(accumulator, currentFilename) =>
|
||||
accumulator.toLowerCase().replace(/\.[^/.]+$/, "") + "\n" +
|
||||
currentFilename.toLowerCase().replace(/\.[^/.]+$/, ""))+'\n';
|
||||
accumulator.toLowerCase().replace(/\.[^/.]+$/, '') +
|
||||
'\n' +
|
||||
currentFilename.toLowerCase().replace(/\.[^/.]+$/, '')
|
||||
) + '\n';
|
||||
fs.writeFileSync('glossary/keyword_database', output);
|
||||
} catch (err) {
|
||||
console.log(`${chalk.red('ERROR!')} During glossary keyword_database generation: ${err}`);
|
||||
|
||||
@ -10,27 +10,34 @@ const util = require('../util');
|
||||
const glossaryFiles = util.getFilesInDir('./glossary', true, ['keyword_database', 'README.md']);
|
||||
const fileTitles = [];
|
||||
|
||||
const getGlossaryTermMarkdownBlock = (fileName) => {
|
||||
const getGlossaryTermMarkdownBlock = fileName => {
|
||||
let fileContent = fs.readFileSync(fileName, 'utf8');
|
||||
|
||||
let title = fileContent.match(/###[^\n]*/)[0].replace('### ', '').trim();
|
||||
let title = fileContent
|
||||
.match(/###[^\n]*/)[0]
|
||||
.replace('### ', '')
|
||||
.trim();
|
||||
// let description = fileContent.replace(title, '').trim();
|
||||
fileTitles.push(title);
|
||||
|
||||
return fileContent.trim() + "\n";
|
||||
return fileContent.trim() + '\n';
|
||||
};
|
||||
|
||||
const glossaryFilesContentReducer = (accumulator, currentFilename) => {
|
||||
// handle first array item
|
||||
if (accumulator === glossaryFiles[0]) {
|
||||
return getGlossaryTermMarkdownBlock(accumulator) + "\n" + getGlossaryTermMarkdownBlock(currentFilename);
|
||||
return (
|
||||
getGlossaryTermMarkdownBlock(accumulator) +
|
||||
'\n' +
|
||||
getGlossaryTermMarkdownBlock(currentFilename)
|
||||
);
|
||||
}
|
||||
return accumulator + "\n" + getGlossaryTermMarkdownBlock(currentFilename);
|
||||
return accumulator + '\n' + getGlossaryTermMarkdownBlock(currentFilename);
|
||||
};
|
||||
|
||||
const getTermLinkMarkdownBlock = (termTitle) => {
|
||||
const getTermLinkMarkdownBlock = termTitle => {
|
||||
let anchor = util.getMarkDownAnchor(termTitle);
|
||||
return `* [\`${termTitle}\`](#${anchor})` + "\n";
|
||||
return `* [\`${termTitle}\`](#${anchor})` + '\n';
|
||||
};
|
||||
|
||||
const glossaryTableOfContentsReducer = (accumulator, currentFile) => {
|
||||
@ -42,13 +49,9 @@ const glossaryTableOfContentsReducer = (accumulator, currentFile) => {
|
||||
|
||||
try {
|
||||
const fileContents = glossaryFiles.reduce(glossaryFilesContentReducer);
|
||||
const TOC = "## Table of Contents\n\n" + fileTitles.reduce(glossaryTableOfContentsReducer);
|
||||
const TOC = '## Table of Contents\n\n' + fileTitles.reduce(glossaryTableOfContentsReducer);
|
||||
|
||||
const README =
|
||||
"# 30-seconds-of-code JavaScript Glossary\n\n" +
|
||||
TOC +
|
||||
"\n\n" +
|
||||
fileContents;
|
||||
const README = '# 30-seconds-of-code JavaScript Glossary\n\n' + TOC + '\n\n' + fileContents;
|
||||
fs.writeFileSync('glossary/README.md', README);
|
||||
} catch (err) {
|
||||
console.log(`${chalk.red('ERROR!')} During glossary README generation: ${err}`);
|
||||
|
||||
@ -25,25 +25,58 @@ locales.forEach(locale => {
|
||||
const snippetHash = util.hashData(snippets[snippet]);
|
||||
if (locData.hasOwnProperty(snippetName)) {
|
||||
if (locData[snippetName].hash !== snippetHash) {
|
||||
existingData = existingData.indexOf(' => '+snippetHash) !== -1 ? existingData : existingData.replace(locData[snippetName].hash, locData[snippetName].hash+' => '+snippetHash);
|
||||
hashChanges.push({snippetName, oldHash: locData[snippetName].hash.split(' => ')[0], newHash: snippetHash});
|
||||
existingData =
|
||||
existingData.indexOf(' => ' + snippetHash) !== -1
|
||||
? existingData
|
||||
: existingData.replace(
|
||||
locData[snippetName].hash,
|
||||
locData[snippetName].hash + ' => ' + snippetHash
|
||||
);
|
||||
hashChanges.push({
|
||||
snippetName,
|
||||
oldHash: locData[snippetName].hash.split(' => ')[0],
|
||||
newHash: snippetHash
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
newData.push(`\n'${snippetName}' : {
|
||||
'description': \`${snippets[snippet].split('```js')[0].replace(/`/g, '\\`')}\`,
|
||||
'comments': [${(snippets[snippet].match(COMMENT_REGEX) || []).map(v => '`'+v.replace(/`/g,'\\`')+'`')}],
|
||||
'comments': [${(snippets[snippet].match(COMMENT_REGEX) || []).map(
|
||||
v => '`' + v.replace(/`/g, '\\`') + '`'
|
||||
)}],
|
||||
'hash': '${snippetHash}'
|
||||
}`);
|
||||
}
|
||||
});
|
||||
if(!fs.existsSync(path.join(LOCALE_PATH,locale+'.js')) || !existingData.length) existingData = `module.exports = {
|
||||
if (!fs.existsSync(path.join(LOCALE_PATH, locale + '.js')) || !existingData.length)
|
||||
existingData = `module.exports = {
|
||||
'locale': {
|
||||
'locale': '${locale}'
|
||||
}};`;
|
||||
fs.writeFileSync(path.join(LOCALE_PATH,locale+'.js'), newData.length ? `${existingData.trim().slice(0,-2)},${newData.join(',')}};` : existingData);
|
||||
fs.writeFileSync(path.join(LOCALE_PATH,locale+'_log'), `${new Date()}
|
||||
fs.writeFileSync(
|
||||
path.join(LOCALE_PATH, locale + '.js'),
|
||||
newData.length ? `${existingData.trim().slice(0, -2)},${newData.join(',')}};` : existingData
|
||||
);
|
||||
fs.writeFileSync(
|
||||
path.join(LOCALE_PATH, locale + '_log'),
|
||||
`${new Date()}
|
||||
Hash changes: ${hashChanges.length}
|
||||
|
||||
${hashChanges.length ? hashChanges.map(v => ('Snippet name:' + v.snippetName +'\n Old hash: ' + v.oldHash + '\n New hash: ' + v.newHash + '\n')).join('\n') : ''}`);
|
||||
${
|
||||
hashChanges.length
|
||||
? hashChanges
|
||||
.map(
|
||||
v =>
|
||||
'Snippet name:' +
|
||||
v.snippetName +
|
||||
'\n Old hash: ' +
|
||||
v.oldHash +
|
||||
'\n New hash: ' +
|
||||
v.newHash +
|
||||
'\n'
|
||||
)
|
||||
.join('\n')
|
||||
: ''
|
||||
}`
|
||||
);
|
||||
});
|
||||
|
||||
@ -7,8 +7,14 @@ const cp = require('child_process');
|
||||
const path = require('path');
|
||||
const chalk = require('chalk');
|
||||
const util = require('./util');
|
||||
if(util.isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') {
|
||||
console.log(`${chalk.green('NOBUILD')} Module build terminated, not a cron job or a custom build!`);
|
||||
if (
|
||||
util.isTravisCI() &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
|
||||
) {
|
||||
console.log(
|
||||
`${chalk.green('NOBUILD')} Module build terminated, not a cron job or a custom build!`
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
// Set variables for paths
|
||||
@ -32,10 +38,7 @@ try {
|
||||
let exportStr = 'export default {';
|
||||
// Read all snippets and store them appropriately
|
||||
for (const snippet of snippets) {
|
||||
const snippetData = fs.readFileSync(
|
||||
path.join(SNIPPETS_PATH, snippet),
|
||||
'utf8'
|
||||
);
|
||||
const snippetData = fs.readFileSync(path.join(SNIPPETS_PATH, snippet), 'utf8');
|
||||
const snippetName = snippet.replace('.md', '');
|
||||
// Check if a snippet is Node-only
|
||||
const isNodeSnippet = tagDatabase
|
||||
|
||||
@ -28,9 +28,8 @@ console.time('Tagger');
|
||||
snippets = util.readSnippets(snippetsPath);
|
||||
// Load tag data from the database
|
||||
tagDbData = util.readTags();
|
||||
tagDbStats = Object.entries(tagDbData)
|
||||
.reduce((acc, val) => {
|
||||
val[1].forEach(v => acc.hasOwnProperty(v) ? acc[v]++ : (acc[v] = 1));
|
||||
tagDbStats = Object.entries(tagDbData).reduce((acc, val) => {
|
||||
val[1].forEach(v => (acc.hasOwnProperty(v) ? acc[v]++ : (acc[v] = 1)));
|
||||
return acc;
|
||||
}, {});
|
||||
// Update the listing of snippets in tag_database and log the statistics, along with missing scripts
|
||||
@ -40,7 +39,9 @@ try {
|
||||
tagDbData.hasOwnProperty(snippet[0].slice(0, -3)) &&
|
||||
tagDbData[snippet[0].slice(0, -3)].join(',').trim()
|
||||
)
|
||||
output += `${snippet[0].slice(0, -3)}:${tagDbData[snippet[0].slice(0, -3)].join(',').trim()}\n`;
|
||||
output += `${snippet[0].slice(0, -3)}:${tagDbData[snippet[0].slice(0, -3)]
|
||||
.join(',')
|
||||
.trim()}\n`;
|
||||
else {
|
||||
output += `${snippet[0].slice(0, -3)}:uncategorized\n`;
|
||||
missingTags++;
|
||||
@ -55,7 +56,9 @@ try {
|
||||
}
|
||||
// Log statistics for the tag_database file
|
||||
console.log(`\n${chalk.bgWhite(chalk.black('=== TAG STATS ==='))}`);
|
||||
for (let tagData of Object.entries(tagDbStats).filter(v => v[0] !== 'undefined').sort((a,b) => a[0].localeCompare(b[0])))
|
||||
for (let tagData of Object.entries(tagDbStats)
|
||||
.filter(v => v[0] !== 'undefined')
|
||||
.sort((a, b) => a[0].localeCompare(b[0])))
|
||||
console.log(`${chalk.green(tagData[0])}: ${tagData[1]} snippets`);
|
||||
console.log(
|
||||
`${chalk.blue("New untagged snippets (will be tagged as 'uncategorized'):")} ${missingTags}\n`
|
||||
|
||||
@ -4,11 +4,16 @@
|
||||
*/
|
||||
|
||||
// Load modules
|
||||
const fs = require('fs-extra'), path = require('path');
|
||||
const fs = require('fs-extra'),
|
||||
path = require('path');
|
||||
const childProcess = require('child_process');
|
||||
const chalk = require('chalk');
|
||||
const util = require('./util');
|
||||
if(util.isTravisCI() && process.env['TRAVIS_EVENT_TYPE'] !== 'cron' && process.env['TRAVIS_EVENT_TYPE'] !== 'api') {
|
||||
if (
|
||||
util.isTravisCI() &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'cron' &&
|
||||
process.env['TRAVIS_EVENT_TYPE'] !== 'api'
|
||||
) {
|
||||
console.log(`${chalk.green('NOBUILD')} Testing terminated, not a cron job or a custom build!`);
|
||||
process.exit(0);
|
||||
}
|
||||
@ -20,8 +25,11 @@ const TEST_PATH = './test';
|
||||
// Array of snippet names
|
||||
const snippetFiles = [];
|
||||
|
||||
const snippetFilesActive = fs.readdirSync(SNIPPETS_ACTIVE, 'utf8').map(fileName => fileName.slice(0, -3));
|
||||
const snippetFilesArchive = fs.readdirSync(SNIPPETS_ARCHIVE, 'utf8')
|
||||
const snippetFilesActive = fs
|
||||
.readdirSync(SNIPPETS_ACTIVE, 'utf8')
|
||||
.map(fileName => fileName.slice(0, -3));
|
||||
const snippetFilesArchive = fs
|
||||
.readdirSync(SNIPPETS_ARCHIVE, 'utf8')
|
||||
.filter(fileName => !fileName.includes('README')) // -> Filters out main README.md file in Archieve which isn't a snippet
|
||||
.map(fileName => fileName.slice(0, -3));
|
||||
|
||||
@ -38,7 +46,9 @@ snippetFiles
|
||||
return fileName;
|
||||
})
|
||||
.map(fileName => {
|
||||
const activeOrArchive = snippetFilesActive.includes(fileName) ? SNIPPETS_ACTIVE : SNIPPETS_ARCHIVE;
|
||||
const activeOrArchive = snippetFilesActive.includes(fileName)
|
||||
? SNIPPETS_ACTIVE
|
||||
: SNIPPETS_ARCHIVE;
|
||||
// Grab snippetData
|
||||
const fileData = fs.readFileSync(path.join(activeOrArchive, `${fileName}.md`), 'utf8');
|
||||
// Grab snippet Code blocks
|
||||
@ -85,8 +95,7 @@ snippetFiles
|
||||
try {
|
||||
fs.writeFileSync(path.join(TEST_PATH, 'testlog'), `Test log for: ${new Date().toString()}\n`);
|
||||
childProcess.execSync(`npm test`);
|
||||
}
|
||||
catch (e) {
|
||||
} catch (e) {
|
||||
fs.appendFileSync(path.join(TEST_PATH, 'testlog'));
|
||||
}
|
||||
console.timeEnd('Tester');
|
||||
|
||||
@ -3,8 +3,10 @@ const fs = require('fs-extra'),
|
||||
chalk = require('chalk'),
|
||||
crypto = require('crypto');
|
||||
|
||||
const getMarkDownAnchor = (paragraphTitle) =>
|
||||
paragraphTitle.trim().toLowerCase()
|
||||
const getMarkDownAnchor = paragraphTitle =>
|
||||
paragraphTitle
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\- ]+/g, '')
|
||||
.replace(/\s/g, '-')
|
||||
.replace(/\-+$/, '');
|
||||
@ -66,7 +68,6 @@ const readTags = () => {
|
||||
return data;
|
||||
})
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
// Handle errors (hopefully not!)
|
||||
console.log(`${chalk.red('ERROR!')} During tag database loading: ${err}`);
|
||||
@ -102,7 +103,11 @@ const capitalize = (str, lowerRest = false) =>
|
||||
// Checks if current environment is Travis CI
|
||||
const isTravisCI = () => 'TRAVIS' in process.env && 'CI' in process.env;
|
||||
// Creates a hash for a value using the SHA-256 algorithm.
|
||||
const hashData = val => crypto.createHash('sha256').update(val).digest('hex');
|
||||
const hashData = val =>
|
||||
crypto
|
||||
.createHash('sha256')
|
||||
.update(val)
|
||||
.digest('hex');
|
||||
// Gets the code blocks for a snippet file.
|
||||
const getCodeBlocks = str => {
|
||||
const regex = /```[.\S\s]*?```/g;
|
||||
|
||||
278
scripts/web.js
278
scripts/web.js
@ -19,12 +19,19 @@ const unescapeHTML = str =>
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
''': '\'',
|
||||
''': "'",
|
||||
'"': '"'
|
||||
}[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`.
|
||||
@ -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 = '';
|
||||
@ -114,26 +154,48 @@ if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE']
|
||||
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">📋 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', 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 => {
|
||||
@ -142,13 +204,44 @@ if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE']
|
||||
});
|
||||
});
|
||||
// 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);
|
||||
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,
|
||||
@ -168,10 +261,12 @@ if(!util.isTravisCI() || (util.isTravisCI() && (process.env['TRAVIS_EVENT_TYPE']
|
||||
// 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,8 +280,16 @@ 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>' +
|
||||
.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, '')
|
||||
@ -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"> </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">📋 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 => {
|
||||
@ -280,20 +420,41 @@ try {
|
||||
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">📋 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>`);
|
||||
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>`);
|
||||
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 = 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);
|
||||
@ -347,17 +507,36 @@ try {
|
||||
.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">📋 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>`);
|
||||
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>`);
|
||||
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 = 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}`;
|
||||
|
||||
@ -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);
|
||||
|
||||
Reference in New Issue
Block a user