first commit

This commit is contained in:
2025-05-30 03:09:08 -06:00
parent 99d54737de
commit 1932509066
6221 changed files with 298434 additions and 212 deletions

View File

@ -0,0 +1,116 @@
const less2sass = require("./less2sass");
const less2css = require("./less2css");
const fs = require("fs").promises;
const path = require("path");
const packageJSON = require("../package.json");
const paths = require("./paths");
const styleFileName = "simple-line-icons";
const cheatSheetCssFile = `styles/${styleFileName}.css`;
async function copyFonts(src, dest) {
const entries = await fs.readdir(src, { withFileTypes: true });
for (let entry of entries) {
const srcPath = path.join(src, entry.name);
const destPath = path.join(dest, entry.name);
await fs.copyFile(srcPath, destPath);
}
}
function extension(filePath, extension) {
return filePath.replace(/\.less$/, extension);
}
async function clearDist() {
await fs.rmdir(paths.dist, { recursive: true });
}
async function createDist() {
await fs.mkdir(paths.distStyles, { recursive: true });
await fs.mkdir(paths.distFonts, { recursive: true });
await fs.mkdir(paths.distDoc, { recursive: true });
}
async function clearLegacyDist() {
await Promise.all([
fs.rmdir(paths.legacyCSS, { recursive: true }),
fs.rmdir(paths.legacySCSS, { recursive: true }),
fs.rmdir(paths.legacyLESS, { recursive: true }),
fs.rmdir(paths.legacyFonts, { recursive: true }),
]);
}
async function legacyDist() {
await clearLegacyDist();
try {
await Promise.all([
fs.mkdir(paths.legacyCSS),
fs.mkdir(paths.legacySCSS),
fs.mkdir(paths.legacyLESS),
fs.mkdir(paths.legacyFonts),
]);
} catch (e) {
// exist
}
await Promise.all([
fs.copyFile(paths.distLessFile, paths.legacyLESSFile),
fs.copyFile(paths.distSCSSFile, paths.legacySCSSFile),
fs.copyFile(paths.distCSSFile, paths.legacyCSSFile),
copyFonts(paths.distFonts, paths.legacyFonts),
]);
}
async function generateCheatSheet() {
const cssPath = path.join(extension(paths.distLessFile, ".css"));
const css = await fs.readFile(cssPath, "UTF8");
const regex = /\.(icon-(?:\w+(?:-)?)+):before\s+{\s*content:\s*"(.+)";\s+}/g;
const icons = [];
css.match(regex).forEach((item) => {
let res = regex.exec(item);
if (!res) return;
icons.push(res[1]);
});
const iconHTML = icons
.map(
(icon) => `<div class="icon-preview-box col-xs-6 col-md-3 col-lg-3">
<div class="preview">
<a href="#" class="show-code" title="click to show css class name"><i class="${icon} icons"></i><span class="name">${icon.replace(
/icon-/g,
""
)}</span> <code class="code-preview">.${icon}</code></a>
</div>
</div>`
)
.join("");
const html = (await fs.readFile(paths.chTemplate, "UTF8"))
.replace(/{{version}}/g, packageJSON.version)
.replace(/{{fontCss}}/g, cheatSheetCssFile)
.replace(/{{contents}}/g, iconHTML);
await fs.writeFile(paths.distDocIndex, html);
}
async function compileStyleSheets() {
const buffer = await fs.readFile(paths.sourceLessFile);
const less = buffer.toString();
const css = less2css(less);
const sass = less2sass.convert(less);
await Promise.all([
fs.writeFile(paths.distLessFile, less),
fs.writeFile(paths.distSCSSFile, sass),
fs.writeFile(paths.distCSSFile, css),
]);
}
async function build() {
await clearDist();
await createDist();
await Promise.all([
copyFonts(paths.fontsSrc, paths.distFonts),
compileStyleSheets(),
]);
await Promise.all([legacyDist(), generateCheatSheet()]);
}
(async () => await build())();

View File

@ -0,0 +1,184 @@
<!doctype html>
<html lang="en">
<head>
<title>Simple Line Icons CheatSheet</title>
<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">
<meta name="description" content="Simple line icons">
<meta name="keywords" content="simple, line, icons, icon pack, web icon">
<link rel="stylesheet" href="{{fontCss}}">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/css/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="https://github.com/thesabbir/simple-line-icons">Simple Line Icons </a>
<span class="version">{{version}}</span>
</div>
<div class="collapse navbar-collapse" id="bs-navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li><iframe src="https://ghbtns.com/github-btn.html?user=thesabbir&repo=simple-line-icons&type=fork&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe></li>
<li><iframe src="https://ghbtns.com/github-btn.html?user=thesabbir&repo=simple-line-icons&type=star&count=true" frameborder="0" scrolling="0" width="100px" height="20px"></iframe></li>
<li class="download"><a href="https://github.com/thesabbir/simple-line-icons/archive/master.zip" class="btn btn-success btn-sm">Download</a></li>
</ul>
</div>
</div>
</nav>
<div class="container mt">
<h3 class="text-center">Cheat sheet</h3>
<div class="text-center font-size-changer">
<a href="#" class="small-icons"><i class="icon-info"></i>Small</a> &bull;
<a href="#" class="medium-icons active"><i class="icon-info"></i> Medium</a> &bull;
<a href="#" class="large-icons"><i class="icon-info"></i> Large</a>
</div>
<p class="text-center">Click on the icons to get the icon class name</p>
<div class="quick-search">
<input type="text" id="quick-search" placeholder="Search..." />
<i class="icon-magnifier"></i>
</div>
{{contents}}
</div>
<footer class="footer">
<div class="container">
<p class="pull-left">Brought to you by <a href="https://twitter.com/alreadysabbir">Sabbir</a> & <a href="https://github.com/thesabbir/simple-line-icons#contributors">Contributors</a></p>
<p class="pull-right">
<a href="https://cdnjs.com/libraries/simple-line-icons" class="use-cdn" title="Go to project page on cdnjs.com" target="_blank">Use CDN</a>
<a href="https://github.com/thesabbir/simple-line-icons">Contribute!</a>
</p>
</div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.1/js/bootstrap.min.js"></script>
<script>
$(document).ready(function() {
$('.code-preview').hide();
$('.show-code').click(function (e) {
$(this).children('.name').toggle();
$(this).children('.code-preview').toggle();
e.stopPropagation();
return false;
});
$("#quick-search").keyup(function () {
var srch = $(this).val().trim().toLowerCase();
$(".icon-preview-box").hide()
.filter(function () {
return $(this).html().trim().toLowerCase().indexOf(srch) != -1;
}).show();
});
$(".font-size-changer a").click(function (e) {
e.preventDefault();
$(".font-size-changer .active").removeClass("active");
$(".icon-preview-box").removeClass("small-icons medium-icons large-icons").addClass($(this).attr("class"));
$(this).addClass("active");
});
});
</script>
<style>
.preview {
padding: 15px 0;
position: relative;
height: 100px;
}
.icons {
font-size: 18px;
padding-right: 7px;
}
.code-preview {
display: none;
}
.name {
font-size: 18px;
}
.show-code {
color: #101010;
}
.mt {
padding-top: 50px;
}
.show-code:hover, .show-code:active, .show-code:focus {
color: #252525;
text-decoration: none;
}
.footer {
background: #efefef;
min-height: 60px;
padding: 20px;
}
.navbar-inverse .navbar-brand, .navbar-inverse .navbar-nav > li > a {
color: #ffffff;
}
.navbar-nav > li > iframe {
margin-top: 13px;
}
body {
font-family: "Helvetica Neue", "Roboto", sans-serif;
}
.quick-search {
width: 200px;
margin: 25px auto;
position: relative;
}
.quick-search i {
position: absolute;
left: 7px;
top: 7px;
color: #ccc;
}
.quick-search input {
border: 1px solid #ccc;
border-radius: 3px;
padding: 3px;
text-indent: 22px;
width: 100%;
}
.quick-search input:focus {
border-color: #999;
}
.quick-search input:focus + i {
color: #999;
}
.small-icons, .small-icons .icons {font-size: 8pt; vertical-align: middle;}
.medium-icons {vertical-align: middle;}
.large-icons, .large-icons .icons {font-size: 22pt; vertical-align: middle;}
.font-size-changer a {text-decoration: none; border: 1px solid #fff; border-radius: 3px; display: inline-block; padding: 5px; vertical-align: middle;}
.font-size-changer a.active {border-color: #999; color: #333;}
.version {
font-size: 8px;
color: #eeeeee;
}
.download {
padding: 8px 0 0 8px;
}
.download .btn {
padding-right: 25px;
padding-left: 25px;
height: 32px;
line-height: 0;
}
.use-cdn {
margin-right: 2rem;
}
</style>
</body>
</html>

View File

@ -0,0 +1,11 @@
const less = require("less");
function less2css(content) {
let output = "";
less.render(content, (e, { css }) => {
output = css;
});
return output;
}
module.exports = less2css;

View File

@ -0,0 +1,134 @@
// http://stackoverflow.com/questions/14970224/anyone-know-of-a-good-way-to-convert-from-less-to-sass
// https://github.com/ekryski/less2sass/releases/tag/v1.0.3
// For any deviations, look for comments prefixed with "SIMPLE LINE ICONS DEVIATION:".
function Less2Sass(){
}
Less2Sass.prototype.convert = function(file) {
this.file = file;
this.convertInterpolatedVariables()
.convertVariables()
.convertTildaStrings()
.convertMixins()
.includeMixins()
.convertExtend()
.convertColourHelpers()
.convertFileExtensions()
.convertFunctionUnit();
return this.file;
};
Less2Sass.prototype.includeMixins = function() {
var includeRegex = /^(\s*)\.([a-zA-Z][\w\-]*\(?[^;{}]*\)?;{1}$)/gm;
this.file = this.file.replace(includeRegex, '$1@include $2');
return this;
};
Less2Sass.prototype.convertMixins = function() {
// Simple form: no semicolons.
const mixinRegexNoSemicolon = /^(\s*?)\.([\w\-]*?)\s*\(([\s\S][^\;]+?)?\)\s*\{$/gm;
this.file = this.file.replace(mixinRegexNoSemicolon, '$1@mixin $2($3) {');
// With semicolons.
const mixinRegexWithSemicolon = /^(\s*?)\.([\w\-]*?)\s*\(([\s\S][^\,]+?)?\)\s*\{$/gm;
this.file = this.file.replace(mixinRegexWithSemicolon, function (match, g1, g2, g3) {
return g1 + '@mixin ' + g2 + '(' + g3.replace(/;/g, ',') + ') {';
});
return this;
};
Less2Sass.prototype.convertFunctionUnit = function() {
// Two-args.
const unitTwoArgRegex = /unit\((\S+),(\S+)\)/g;
this.file = this.file.replace(unitTwoArgRegex, '0$2 + $1');
// One-arg.
const unitOneArgRegex = /unit\(([^,]+)\)/g;
this.file = this.file.replace(unitOneArgRegex, 'unit-less($1)');
return this;
};
Less2Sass.prototype.convertExtend = function() {
// http://lesscss.org/features/#extend-feature
// &:extend syntax.
const andExtendRegex = /&:extend\((.[\w]*)\);/g;
this.file = this.file.replace(andExtendRegex, '@extend $1;');
return this;
};
Less2Sass.prototype.convertColourHelpers = function() {
var helperRegex = /spin\(/g;
this.file = this.file.replace(helperRegex, 'adjust-hue(');
// TODO (EK): Flag other colour helpers for manual conversion that SASS does not have
return this;
};
Less2Sass.prototype.convertTildaStrings = function() {
var tildaRegex = /~("|')/g;
this.file = this.file.replace(tildaRegex, '$1');
return this;
};
Less2Sass.prototype.convertInterpolatedVariables = function() {
var interpolationRegex = /@\{(?!(\s|\())/g;
this.file = this.file.replace(interpolationRegex, '#{$');
return this;
};
Less2Sass.prototype.convertVariables = function() {
// Matches any @ that doesn't have 'media ' or 'import ' after it.
//
// SIMPLE LINE ICONS DEVIATION:
// Additionally, we capture the variable name, full variable declaration and if this
// should be considered a default variable for "simple-line-icons"-specific logic for
// creating default variables (because LESS doesn't have the concept of default variable declarations).
//
// For example, if we have a LESS variable that looked like:
//
// @simple-line-font-path: "../fonts/"; // default
//
// The "varDeclaration" group would be 'simple-line-font-path: "../fonts/"', the varName
// group would be "simple-line-font-path" and the isDefault group would have content (indicating
// that this should be output as a default variable).
var varRegex = /@(?!(media|import|mixin|font-face|keyframes)(\s|\())(?<varDeclaration>(?<varName>([^:]*))[^;]*);(?<isDefault>\s*\/\/\s*default)?/g;
// SIMPLE LINE ICONS DEVIATION:
// The "replace" call has been modified so we can append the "!default" string for our
// overridable variables. We only output a variable with the "!default" string if the
// source had a "default" comment.
this.file = this.file.replace(varRegex, function (match, p1, p2, p3, p4, p5, p6, offset, string, groups) {
if (groups.isDefault) {
return `$${groups.varDeclaration} !default;`
}
// The "match" includes the "@" symbol which we want to convert to a "$" for SASS.
return `$${match.substring(1)}`
});
return this;
};
Less2Sass.prototype.convertFileExtensions = function() {
var extensionRegex = /\.less/g;
this.file = this.file.replace(extensionRegex, '.scss');
return this;
};
module.exports = new Less2Sass();

View File

@ -0,0 +1,62 @@
const path = require("path");
/*
* Paths
*/
// root
const root = path.resolve(__dirname, "..");
// filename
const styleFileName = "simple-line-icons";
const lessFileName = `${styleFileName}.less`;
const scssFileName = `${styleFileName}.scss`;
const cssFileName = `${styleFileName}.css`;
// src
const src = path.resolve(root, "src");
const sourceLessFile = path.resolve(src, "styles", lessFileName);
const fontsSrc = path.resolve(src, "fonts");
// dist
const dist = path.join(root, "dist");
const distStyles = path.join(dist, "styles");
const distLessFile = path.join(distStyles, lessFileName);
const distSCSSFile = path.join(distStyles, scssFileName);
const distCSSFile = path.join(distStyles, cssFileName);
const distFonts = path.resolve(dist, "fonts");
// legacy dist
const legacyCSS = path.join(root, "css");
const legacySCSS = path.join(root, "scss");
const legacyLESS = path.join(root, "less");
const legacyFonts = path.resolve(root, "fonts");
const legacyCSSFile = path.join(root, "css", cssFileName);
const legacySCSSFile = path.join(root, "scss", scssFileName);
const legacyLESSFile = path.join(root, "less", lessFileName);
const distDoc = path.resolve(root, "docs");
const distDocIndex = path.resolve(distDoc, "index.html");
// cheetsheet
const chTemplate = path.resolve(__dirname, "cheatsheet.template.html");
module.exports = {
dist,
distStyles,
sourceLessFile,
distLessFile,
fontsSrc,
distFonts,
chTemplate,
distDocIndex,
distDoc,
distCSSFile,
distSCSSFile,
legacyCSSFile,
legacySCSSFile,
legacyLESSFile,
legacyFonts,
legacyLESS,
legacySCSS,
legacyCSS,
};