From 74f543bf04e7986008bf91aae4d59eda2429790a Mon Sep 17 00:00:00 2001
From: codecalm <codecalm@gmail.com>
Date: Mon, 23 Mar 2020 20:28:34 +0100
Subject: iconfont generator

---
 .build/iconfont.html | 117 ++++++++++++++++++++++++++++++++++++++++++
 .build/iconfont.scss |  40 +++++++++++++++
 .gitignore           |   1 +
 gulpfile.js          | 141 ++++++++++++++++++++++++++++++++++++++++++++++++---
 package.json         |  10 +++-
 5 files changed, 300 insertions(+), 9 deletions(-)
 create mode 100644 .build/iconfont.html
 create mode 100644 .build/iconfont.scss

diff --git a/.build/iconfont.html b/.build/iconfont.html
new file mode 100644
index 00000000..a61a6ad3
--- /dev/null
+++ b/.build/iconfont.html
@@ -0,0 +1,117 @@
+<!doctype html>
+<html lang="en">
+<head>
+	<meta charset="UTF-8">
+	<meta name="viewport"
+	      content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
+	<meta http-equiv="X-UA-Compatible" content="ie=edge">
+	<title>Tabler Icons - version <%= v %></title>
+
+	<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600" rel="stylesheet">
+	<link rel="stylesheet" href="./<%= fileName %>.css">
+
+	<style>
+		* { margin: 0; border: 0; outline: 0; box-sizing: border-box; }
+
+		body {
+			font-family: 'Open Sans', sans-serif;
+			background: #fafbfc;
+			font-size: 1rem;
+			padding: 1rem;
+		}
+
+		code {
+			font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+			background: #fafafa;
+			border: 1px solid #f0f0f0;
+			color: #666;
+			padding: 2px 4px;
+			margin-bottom: 2px;
+		}
+
+		.container {
+			max-width: 73rem;
+			margin: 0 auto;
+		}
+
+		.box {
+			padding: 1rem;
+			background: #fff;
+			box-shadow: 0 0 0 1px rgba(0, 0, 0, .05), 0 1px 1px rgba(0, 0, 0, .1);
+			border-radius: 3px;
+		}
+
+		.tabler-icons {
+			display: flex;
+			flex-wrap: wrap;
+			justify-content: space-between;
+		}
+
+		.tabler-icon {
+			width: 10rem;
+			font-size: 12px;
+			text-align: center;
+			padding: .5rem .25rem 2rem;
+		}
+
+		.tabler-icon i {
+			display: block;
+			align-items: center;
+			font-size: 32px;
+			height: 1em;
+			margin-bottom: 1rem;
+		}
+
+		.tabler-icon code {
+			font-size: 10px;
+		}
+
+		.tabler-icon strong {
+			display: block;
+			margin-bottom: .5rem;
+		}
+
+		.tabler-icon-codes {
+			line-height: 2em;
+		}
+
+		.text-muted {
+			color: #999;
+		}
+
+		.header {
+			text-align: center;
+			margin: 2rem 0 3rem;
+		}
+
+
+	</style>
+</head>
+<body>
+<div class="container">
+	<header class="header">
+		<h1>
+			Tabler Icons
+		</h1>
+		<p class="text-muted">version <%= v %></p>
+	</header>
+
+	<div class="box">
+		<div class="tabler-icons">
+			<% glyphs.forEach(function(glyph) { %>
+			<div class="tabler-icon">
+				<i class="ti ti-<%= glyph.name %>"></i>
+				<strong><%= glyph.name %></strong>
+				<div class="tabler-icon-codes">
+					<code>ti ti-<%= glyph.name %></code><br>
+					<code>\<%= glyph.unicode[0].codePointAt(0).toString(16) %></code>
+				</div>
+			</div>
+			<% }) %>
+		</div>
+	</div>
+</div>
+
+
+</body>
+</html>
diff --git a/.build/iconfont.scss b/.build/iconfont.scss
new file mode 100644
index 00000000..97c21d4e
--- /dev/null
+++ b/.build/iconfont.scss
@@ -0,0 +1,40 @@
+/*!
+ * Tabler Icons <%= v %> by tabler - https://tabler.io
+ * License - https://github.com/tabler/tabler-icons/blob/master/LICENSE
+ */
+$ti-font-family: '<%= fileName %>' !default;
+$ti-font-path: './fonts' !default;
+$ti-font-display: null !default;
+$ti-icon-prefix: 'ti' !default;
+
+@font-face {
+  font-family: $ti-font-family;
+  font-style: normal;
+  font-weight: 400;
+  font-display: $ti-font-display;
+  src: url('#{$ti-font-path}/<%= fileName %>.eot');
+  src: url('#{$ti-font-path}/<%= fileName %>.eot?#iefix') format('embedded-opentype'),
+    url('#{$ti-font-path}/<%= fileName %>.woff2') format('woff2'),
+    url('#{$ti-font-path}/<%= fileName %>.woff') format('woff'),
+    url('#{$ti-font-path}/<%= fileName %>.ttf') format('truetype');
+}
+
+.#{$ti-icon-prefix} {
+  font-family: $ti-font-family !important;
+  speak: none;
+  font-style: normal;
+  font-weight: normal;
+  font-variant: normal;
+  text-transform: none;
+  line-height: 1;
+
+  /* Better Font Rendering */
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}
+
+<% glyphs.forEach(function(glyph) { %>
+$ti-icon-<%= glyph.name %>: '\<%= glyph.unicode[0].codePointAt(0).toString(16) %>';<% }); %>
+
+<% glyphs.forEach(function(glyph) { %>
+.#{$ti-icon-prefix}-<%= glyph.name %>:before { content: $ti-icon-<%= glyph.name %>; }<% }); %>
diff --git a/.gitignore b/.gitignore
index bdc37d5f..4cf967de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@ package-lock.json
 Gemfile.lock
 packages/*
 .DS_Store
+icons-outlined/
diff --git a/gulpfile.js b/gulpfile.js
index aca7c770..e39b14e4 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -6,6 +6,11 @@ const gulp = require('gulp'),
 	p = require('./package.json'),
 	zip = require('gulp-zip'),
 	puppeteer = require('puppeteer'),
+	outlineStroke = require('svg-outline-stroke'),
+	iconfont = require('gulp-iconfont'),
+	template = require('lodash.template'),
+	sass = require('node-sass'),
+	cleanCSS = require('clean-css'),
 	argv = require('minimist')(process.argv.slice(2));
 
 async function asyncForEach(array, callback) {
@@ -73,7 +78,7 @@ const createScreenshot = async (filePath) => {
 
 const printChangelog = function (newIcons, modifiedIcons, renamedIcons, pretty = false) {
 	if (newIcons.length > 0) {
-		if(pretty) {
+		if (pretty) {
 			console.log(`### ${newIcons.length} new icons:`);
 
 			newIcons.forEach(function (icon, i) {
@@ -122,7 +127,7 @@ const printChangelog = function (newIcons, modifiedIcons, renamedIcons, pretty =
 	}
 };
 
-const generateIconsPreview = function(files, destFile, cb, columnsCount = 17, paddingOuter = 5) {
+const generateIconsPreview = function (files, destFile, cb, columnsCount = 17, paddingOuter = 5) {
 
 	const padding = 29,
 		iconSize = 24;
@@ -170,10 +175,130 @@ const generateIconsPreview = function(files, destFile, cb, columnsCount = 17, pa
 
 //*********************************************************************************************
 
+gulp.task('iconfont-prepare', function (cb) {
+	cp.exec('mkdir -p icons-outlined/ && rm -fd ./icons-outlined/* && mkdir -p && rm -fd ./iconfont/*', function () {
+		cb();
+	});
+});
+
+gulp.task('iconfont-clean', function (cb) {
+	cp.exec('rm -rf ./icons-outlined', function () {
+		cb();
+	});
+});
+
+gulp.task('iconfont-svg-outline', function (cb) {
+
+	cp.exec('mkdir -p icons-outlined/ && rm -fd ./icons-outlined/*', async () => {
+		let files = glob.sync("./icons/*.svg");
+
+		let iconfontUnicode = {};
+
+		if(fs.existsSync('./iconfont-unicode.json')) {
+			iconfontUnicode = require('./iconfont-unicode');
+		}
+
+		await asyncForEach(files, async function (file) {
+			const name = path.basename(file, '.svg'),
+				unicode = iconfontUnicode[name];
+
+			await console.log('Stroke for:', file, unicode);
+
+			let strokedSVG = fs.readFileSync(file).toString();
+
+			strokedSVG = strokedSVG
+				.replace('width="24"', 'width="1000"')
+				.replace('height="24"', 'height="1000"');
+
+			await outlineStroke(strokedSVG, {
+				optCurve: false,
+				steps: 4,
+				round: 0,
+				centerHorizontally: true,
+				fixedWidth: true,
+				color: 'black'
+			}).then(outlined => {
+				if(unicode) {
+					fs.writeFileSync(`icons-outlined/u${unicode.toUpperCase()}-${name}.svg`, outlined);
+				} else {
+					fs.writeFileSync(`icons-outlined/${name}.svg`, outlined);
+				}
+			}).catch(error => console.log(error));
+		});
+
+		cb();
+	});
+});
+
+gulp.task('iconfont', function () {
+	let maxUnicode = 59905;
+
+	if(fs.existsSync('./iconfont-unicode.json')) {
+		const iconfontUnicode = require('./iconfont-unicode');
+
+		for(const name in iconfontUnicode) {
+			const unicode = parseInt(iconfontUnicode[name], 16);
+
+			maxUnicode = Math.max(maxUnicode, unicode);
+		}
+	}
+	
+	return gulp.src(['icons-outlined/*.svg'])
+		.pipe(iconfont({
+			fontName: 'tabler-icons',
+			prependUnicode: true,
+			formats: ['ttf', 'eot', 'woff', 'woff2'],
+			normalize: true,
+			startUnicode: maxUnicode
+		}))
+		.on('glyphs', function (glyphs, options) {
+			//glyphs json
+			let glyphsObject = {};
+
+			glyphs.forEach(function (glyph) {
+				glyphsObject[glyph.name] = glyph.unicode[0].codePointAt(0).toString(16);
+			});
+
+			fs.writeFileSync(`iconfont-unicode.json`, JSON.stringify(glyphsObject));
+
+			//css
+			options['glyphs'] = glyphs;
+			options['v'] = p.version;
+
+			const compiled = template(fs.readFileSync('.build/iconfont.scss').toString());
+			const result = compiled(options);
+
+			fs.writeFileSync('iconfont/tabler-icons.scss', result);
+
+			//html
+			const compiledHtml = template(fs.readFileSync('.build/iconfont.html').toString());
+			const resultHtml = compiledHtml(options);
+
+			fs.writeFileSync('iconfont/tabler-icons.html', resultHtml);
+		})
+		.pipe(gulp.dest('iconfont/fonts'));
+});
+
+gulp.task('iconfont-css', function (cb) {
+	sass.render({
+		file: 'iconfont/tabler-icons.scss',
+		outputStyle: 'expanded'
+	}, function (err, result) {
+		fs.writeFileSync('iconfont/tabler-icons.css', result.css);
+
+		const cleanOutput = new cleanCSS({}).minify(result.css);
+		fs.writeFileSync('iconfont/tabler-icons.min.css', cleanOutput.styles);
+
+		cb();
+	});
+});
+
+gulp.task('build-iconfont', gulp.series('iconfont-prepare', 'iconfont-svg-outline', 'iconfont', 'iconfont-css', 'iconfont-clean'));
+
 gulp.task('build-zip', function () {
 	const version = p.version;
 
-	return gulp.src('{icons/**/*,icons-png/**/*,tabler-sprite.svg,tabler-sprite-nostroke.svg}')
+	return gulp.src('{icons/**/*,icons-png/**/*,iconfont/**/*,tabler-sprite.svg,tabler-sprite-nostroke.svg}')
 		.pipe(zip(`tabler-icons-${version}.zip`))
 		.pipe(gulp.dest('packages'))
 });
@@ -319,7 +444,7 @@ gulp.task('changelog-commit', function (cb) {
 gulp.task('changelog', function (cb) {
 	const version = argv['latest-tag'] || `v${p.version}`;
 
-	if(version) {
+	if (version) {
 		cp.exec(`git diff ${version} HEAD --name-status`, function (err, ret) {
 
 			let newIcons = [], modifiedIcons = [], renamedIcons = [];
@@ -351,7 +476,7 @@ gulp.task('changelog-image', function (cb) {
 	const version = argv['latest-version'] || `${p.version}`,
 		newVersion = argv['new-version'] || `${p.version}`;
 
-	if(version) {
+	if (version) {
 		cp.exec(`git diff v${version} HEAD --name-status`, function (err, ret) {
 
 			let newIcons = [];
@@ -360,11 +485,11 @@ gulp.task('changelog-image', function (cb) {
 				newIcons.push(fileName);
 			});
 
-			newIcons = newIcons.map(function(icon){
+			newIcons = newIcons.map(function (icon) {
 				return `./icons/${icon}.svg`;
 			});
 
-			if(newIcons.length > 0) {
+			if (newIcons.length > 0) {
 				generateIconsPreview(newIcons, `.github/tabler-icons-${newVersion}.svg`, cb, 6, 24);
 			} else {
 				cb();
@@ -390,4 +515,4 @@ gulp.task('svg-to-png', gulp.series('build-jekyll', 'clean-png', async (cb) => {
 	cb();
 }));
 
-gulp.task('build', gulp.series('optimize', 'build-jekyll', 'build-copy', 'icons-sprite', 'icons-preview', 'svg-to-png', 'changelog-image', 'build-zip'));
+gulp.task('build', gulp.series('optimize', 'build-jekyll', 'build-copy', 'icons-sprite', 'icons-preview', 'svg-to-png', 'build-iconfont', 'changelog-image', 'build-zip'));
diff --git a/package.json b/package.json
index 89fec1ff..d09d581f 100644
--- a/package.json
+++ b/package.json
@@ -17,6 +17,7 @@
   "files": [
     "icons/*",
     "icons-png/*",
+    "iconfont/*",
     "tabler-sprite.svg",
     "tabler-sprite-nostroke.svg"
   ],
@@ -29,12 +30,15 @@
   },
   "description": "",
   "devDependencies": {
+    "clean-css": "4.2.3",
     "glob": "7.1.6",
     "gulp": "4.0.2",
+    "gulp-iconfont": "10.0.3",
     "gulp-zip": "5.0.1",
     "minimist": "1.2.5",
     "puppeteer": "2.1.1",
-    "release-it": "13.1.2"
+    "release-it": "13.1.2",
+    "svg-outline-stroke": "1.2.4"
   },
   "release-it": {
     "hooks": {
@@ -50,5 +54,9 @@
     "github": {
       "release": true
     }
+  },
+  "dependencies": {
+    "lodash.template": "^4.5.0",
+    "node-sass": "^4.13.1"
   }
 }
-- 
cgit v1.2.1