const gulp = require('gulp'), cp = require('child_process'), glob = require('glob'), fs = require('fs'), path = require('path'), p = require('./package.json'), zip = require('gulp-zip'), puppeteer = require('puppeteer'); async function asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array); } } const svgToPng = async (filePath, destination) => { filePath = path.join(__dirname, filePath); const htmlFilePath = path.join("file:", filePath); const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport({ height: 24, width: 24, deviceScaleFactor: 10 }); await page.goto(htmlFilePath); await page.screenshot({ path: path.join(__dirname, destination), omitBackground: true, fullPage: true }); await browser.close(); return page; }; const createScreenshot = async (filePath) => { try { filePath = path.join(__dirname, filePath); const fileName = filePath.replace('.svg', ''); const htmlFilePath = path.join("file:", filePath); const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport({ height: 100, width: 100 }); await page.goto(htmlFilePath); await page.screenshot({ path: `${fileName}.png`, omitBackground: false, fullPage: true }); await browser.close(); } catch (error) { console.error(error); throw Error(error); } }; gulp.task('icons-sprite', function (cb) { glob("_site/icons/*.svg", {}, function (er, files) { let svgContent = ''; files.forEach(function (file, i) { let name = path.basename(file, '.svg'), svgFile = fs.readFileSync(file), svgFileContent = svgFile.toString(); svgFileContent = svgFileContent .replace(/]+>/g, '') .replace(/<\/svg>/g, '') .replace(/\n+/g, '') .replace(/>\s+<') .trim(); svgContent += `${svgFileContent}` }); let svg = `${svgContent}`; fs.writeFileSync('tabler-sprite.svg', svg); cb(); }); }); gulp.task('icons-preview', function (cb) { const columnsCount = 17, padding = 29, paddingOuter = 5, iconSize = 24; glob("_site/icons/*.svg", {}, function (er, files) { const iconsCount = files.length, rowsCount = Math.ceil(iconsCount / columnsCount), width = columnsCount * (iconSize + padding) + 2 * paddingOuter - padding, height = rowsCount * (iconSize + padding) + 2 * paddingOuter - padding; let svgContentSymbols = '', svgContentIcons = '', x = paddingOuter, y = paddingOuter; files.forEach(function (file, i) { let name = path.basename(file, '.svg'); let svgFile = fs.readFileSync(file), svgFileContent = svgFile.toString(); svgFileContent = svgFileContent .replace('', '') .replace(/\n\s+/g, ''); svgContentSymbols += `\t${svgFileContent}\n`; svgContentIcons += `\t\n`; x += padding + iconSize; if (i % columnsCount === columnsCount - 1) { x = paddingOuter; y += padding + iconSize; } }); const svgContent = `\n${svgContentSymbols}\n${svgContentIcons}\n`; fs.writeFileSync('.github/icons.svg', svgContent); createScreenshot('.github/icons.svg'); cb(); }); }); gulp.task('icons-stroke', function (cb) { const icon = "disabled", strokes = ['.5', '1', '1.5', '2', '2.75'], svgFileContent = fs.readFileSync(`_site/icons/${icon}.svg`).toString(), padding = 16, paddingOuter = 5, iconSize = 64, width = (strokes.length * (iconSize + padding) - padding) + paddingOuter * 2, height = iconSize + paddingOuter * 2; let svgContentSymbols = '', svgContentIcons = '', x = paddingOuter; strokes.forEach(function (stroke) { let svgFileContentStroked = svgFileContent .replace('', '') .replace(/\n\s+/g, ''); svgContentSymbols += `\t${svgFileContentStroked}\n`; svgContentIcons += `\t\n`; x += padding + iconSize; }); const svgContent = `\n${svgContentSymbols}\n${svgContentIcons}\n`; fs.writeFileSync('icons-stroke.svg', svgContent); createScreenshot('icons-stroke.svg'); cb(); }); gulp.task('optimize', function (cb) { glob("src/_icons/*.svg", {}, function (er, files) { files.forEach(function (file, i) { let svgFile = fs.readFileSync(file), svgFileContent = svgFile.toString(); svgFileContent = svgFileContent .replace(/><\/(polyline|line|rect|circle|path)>/g, '/>') .replace(/rx="([^"]+)"\s+ry="\1"/g, 'rx="$1"') .replace(/\s?\/>/g, ' />') .replace(/\n\s*<(line|circle|path|polyline)/g, "\n <$1") .replace(/polyline points="([0-9.]+)\s([0-9.]+)\s([0-9.]+)\s([0-9.]+)"/g, 'line x1="$1" y1="$2" x2="$3" y2="$4"') .replace(/\n\n+/g, "\n"); fs.writeFileSync(file, svgFileContent); }); cb(); }); }); gulp.task('build-zip', function(cb) { const version = p.version; return gulp.src('{icons/**/*,icons-png/**/*,tabler-sprite.svg}') .pipe(zip(`${version}.zip`)) .pipe(gulp.dest('packages')) }); gulp.task('build-jekyll', function(cb){ cp.exec('bundle exec jekyll build', function() { cb(); }); }); gulp.task('build-copy', function(cb){ cp.exec('mkdir -p icons/ && rm -fd ./icons/* && cp ./_site/icons/* ./icons', function() { cb(); }); }); gulp.task('clean-png', function(cb){ cp.exec('rm -fd ./icons-png/*', function() { cb(); }); }); gulp.task('svg-to-png', gulp.series('build-jekyll', 'clean-png', async (cb) => { let files = glob.sync("_site/icons/*.svg"); await asyncForEach(files, async function (file, i) { let name = path.basename(file, '.svg'); console.log('name', name); await svgToPng(file, `icons-png/${name}.png`); }); cb(); })); gulp.task('build', gulp.series('build-jekyll', 'build-copy', 'build-zip'));