2020-05-21 23:48:06 +02:00
|
|
|
// Build tool for generating README.md
|
2020-05-22 04:38:21 +02:00
|
|
|
// TODO: Add support for section-specific comments
|
2020-05-21 23:48:06 +02:00
|
|
|
|
|
|
|
const os = require('os');
|
|
|
|
const path = require('path');
|
|
|
|
const fs = require('fs-extra');
|
|
|
|
const YAML = require('yaml');
|
|
|
|
|
2020-05-22 04:29:03 +02:00
|
|
|
// A hacky sort of "class" to contain methods for each section
|
|
|
|
const BUILD_SECTION = {
|
|
|
|
// TODO: Make more of these YAML-based functions
|
2020-05-24 02:33:07 +02:00
|
|
|
header: () => readFile('md/_header.md'),
|
|
|
|
index: () => readFile('md/_index.md'),
|
|
|
|
contributing: () => readFile('md/_contributing.md'),
|
2020-05-22 04:29:03 +02:00
|
|
|
browserExtensions: () => readFile('md/_browserExtensions.md'),
|
2020-05-24 02:33:07 +02:00
|
|
|
disclaimer: () => readFile('md/_disclaimer.md'),
|
|
|
|
webBasedProducts: () => generateCategorySection('Web-based products', readYaml()['web based products']),
|
|
|
|
operatingSystems: () => generateCategorySection('Operating systems', readYaml()['operating systems']),
|
|
|
|
desktopApps: () => generateCategorySection('Desktop apps', readYaml()['desktop applications']),
|
|
|
|
mobileApps: () => generateCategorySection('Mobile apps', readYaml()['desktop applications']),
|
|
|
|
hardware: () => generateCategorySection('Hardware', readYaml()['hardware']),
|
|
|
|
useful: () => '# Useful links, tools, and advice',
|
|
|
|
resources: () => readFile('md/_resources.md'),
|
|
|
|
books: () => readFile('md/_books.md'),
|
|
|
|
blogs: () => readFile('md/_blogs.md'),
|
|
|
|
news: () => readFile('md/_news.md'),
|
|
|
|
lighterSide: () => readFile('md/_lighterSide.md'),
|
|
|
|
closingRemarks: () => readFile('md/_closingRemarks.md')
|
2020-05-22 04:29:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Main method
|
|
|
|
*/
|
2020-05-21 23:48:06 +02:00
|
|
|
function __main__() {
|
2020-05-22 04:29:03 +02:00
|
|
|
// dgSectionData will be join at the end and represents the full contents of README.md
|
|
|
|
let dgSectionData = [];
|
|
|
|
|
|
|
|
// Add all the sections
|
|
|
|
dgSectionData.push(BUILD_SECTION.header());
|
|
|
|
dgSectionData.push(BUILD_SECTION.index());
|
|
|
|
dgSectionData.push(BUILD_SECTION.contributing());
|
|
|
|
dgSectionData.push(BUILD_SECTION.browserExtensions());
|
|
|
|
dgSectionData.push(BUILD_SECTION.disclaimer());
|
|
|
|
dgSectionData.push(BUILD_SECTION.webBasedProducts());
|
|
|
|
dgSectionData.push(BUILD_SECTION.operatingSystems());
|
|
|
|
dgSectionData.push(BUILD_SECTION.desktopApps());
|
|
|
|
dgSectionData.push(BUILD_SECTION.mobileApps());
|
|
|
|
dgSectionData.push(BUILD_SECTION.hardware());
|
|
|
|
dgSectionData.push(BUILD_SECTION.useful());
|
|
|
|
dgSectionData.push(BUILD_SECTION.resources());
|
|
|
|
dgSectionData.push(BUILD_SECTION.books());
|
|
|
|
dgSectionData.push(BUILD_SECTION.blogs());
|
|
|
|
dgSectionData.push(BUILD_SECTION.news());
|
|
|
|
dgSectionData.push(BUILD_SECTION.lighterSide());
|
|
|
|
dgSectionData.push(BUILD_SECTION.closingRemarks());
|
|
|
|
|
|
|
|
// Write to the README file
|
2020-05-24 02:33:07 +02:00
|
|
|
fs.writeFileSync(path.join(__dirname, 'README.md'), dgSectionData.join(os.EOL + os.EOL));
|
2020-05-22 04:29:03 +02:00
|
|
|
|
2020-05-24 02:33:07 +02:00
|
|
|
console.log('Done!')
|
2020-05-22 04:29:03 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Synchronously reads a file using fs-extra and path.join()
|
|
|
|
* @param {String} filename The file to read
|
|
|
|
*/
|
|
|
|
function readFile(filename) {
|
|
|
|
return fs.readFileSync(path.join(__dirname, filename)).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads degoogle.yml
|
|
|
|
*/
|
|
|
|
function readYaml() {
|
|
|
|
return YAML.parse(fs.readFileSync(path.join(__dirname, 'degoogle.yml')).toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates a major section or "category" such as Mobile Apps
|
|
|
|
* @param {String} header Title for section
|
|
|
|
* @param {Object} data Object of data to populate README.md with
|
|
|
|
*/
|
|
|
|
function generateCategorySection(header, data) {
|
|
|
|
if (!data) return '';
|
|
|
|
|
|
|
|
// Set the header to HTML <h5>
|
|
|
|
let categorySection = '## ' + header + os.EOL + os.EOL;
|
|
|
|
|
|
|
|
// Generate service sections for this category
|
|
|
|
Object.keys(data).forEach((key) => categorySection = categorySection.concat(generateServiceSection(data[key]) + os.EOL + os.EOL));
|
|
|
|
|
|
|
|
return categorySection;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generates a service (such as Gmail) section to be placed under a category section
|
2020-05-24 02:33:07 +02:00
|
|
|
* @param {Array} data
|
2020-05-22 04:29:03 +02:00
|
|
|
*/
|
|
|
|
function generateServiceSection(data) {
|
|
|
|
// Start the section with an <h4> header and the start of a Markdown table
|
|
|
|
let serviceSection = `#### ${data[0].title + os.EOL + os.EOL}| Name | Eyes | Description |${os.EOL}| ---- | ---- | ----------- |${os.EOL}`;
|
|
|
|
|
|
|
|
// Iterate over each alternative service and add it to the table
|
|
|
|
data.forEach(item => {
|
|
|
|
// If the object has length one, it's just the title
|
|
|
|
if (Object.keys(item).length == 1) return;
|
2020-05-21 23:48:06 +02:00
|
|
|
|
2020-05-22 04:29:03 +02:00
|
|
|
// Build the cells for the table
|
2020-05-21 23:48:06 +02:00
|
|
|
let name = `[${item.name}](${item.url})`;
|
|
|
|
let eyes = item.eyes ? `**${item.eyes}-eyes**` : '';
|
2020-05-22 01:02:11 +02:00
|
|
|
let text = item.text.trim();
|
2020-05-21 23:48:06 +02:00
|
|
|
|
2020-05-22 04:29:03 +02:00
|
|
|
// Build the row
|
|
|
|
let tableItem = `| ${name} | ${eyes} | ${text} |`;
|
2020-05-24 02:33:07 +02:00
|
|
|
|
2020-05-22 04:29:03 +02:00
|
|
|
// Add the row to the table
|
|
|
|
serviceSection = serviceSection.concat(tableItem + os.EOL)
|
2020-05-21 23:48:06 +02:00
|
|
|
});
|
|
|
|
|
2020-05-22 04:29:03 +02:00
|
|
|
return serviceSection;
|
2020-05-21 23:48:06 +02:00
|
|
|
}
|
|
|
|
|
2020-05-24 02:33:07 +02:00
|
|
|
__main__();
|