Created
March 24, 2016 13:09
-
-
Save mir4a/99f3731a74ae63c4ef94 to your computer and use it in GitHub Desktop.
get colors (hex, rgb, rgba) from predefined directory. Work on Node 5.9
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const path = require('path'); | |
const dirToParse = 'app/assets/stylesheets/nv'; | |
const skipFile = 'app/assets/stylesheets/nv/shared/colors.scss' | |
const colorRegexp = /(#[A-Z\d]{3}\b|#[A-Z\d]{6}\b)|(rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?([, \.\d]+)?\))/gi; | |
const variableMap = new Map(); | |
const process = require('process'); | |
const args = processArguments(process.argv); | |
var colorMap = new Map(); | |
var fileCounter = 0; | |
console.log(process.argv); | |
function processArguments( arg ) { | |
return arg.length > 2 ? arg.splice(2) : dirToParse; | |
} | |
function searchForColorInFile(data, filePath) { | |
var result = []; | |
var test; | |
var lines = data.split('\n'); | |
for (var i = 0, len = lines.length; i < len; i++) { | |
var lineStr = `${filePath}:${i+1}:`; | |
while (test = colorRegexp.exec(lines[i])) { | |
addToMap(test[0], lineStr + (test.index + 1), colorMap); | |
result.push(test[0]); | |
} | |
} | |
return result; | |
} | |
function addToMap(color, place, map) { | |
var normalizedColor = color.toLowerCase(); | |
var longColor = convertShortHEXtoLong(normalizedColor); | |
if (map.has(longColor)) { | |
var val = map.get(longColor); | |
val.place.push(place); | |
val.index = getColorIndex(longColor); | |
map.set(longColor, val); | |
} else { | |
var val2 = { | |
place: [], | |
index: 0 | |
}; | |
val2.place.push(place); | |
val2.index = getColorIndex(longColor); | |
map.set(longColor, val2); | |
} | |
return map; | |
} | |
function pathType(path) { | |
var stat = fs.statSync(path); | |
var type; | |
if (stat.isFile()) type = 'FILE'; | |
else if (stat.isDirectory()) type = 'DIRECTORY'; | |
else type = undefined; | |
return type; | |
} | |
function processDir(path) { | |
var files = []; | |
if (typeof path === 'array') { | |
for (var el of path) { | |
files = fs.readdirSync(el); | |
main(files, ela); | |
} | |
} else { | |
files = fs.readdirSync(path); | |
main(files, path); | |
} | |
} | |
function main(files, dir) { | |
dir = dir ? dir : dirToParse; | |
var data, | |
filePath, | |
pType, | |
colors; | |
for (var file of files) { | |
filePath = path.resolve(dir, file); | |
pType = pathType(filePath); | |
if (pType === 'FILE') { | |
if (filePath === path.resolve(skipFile)) continue; | |
data = fs.readFileSync(filePath, 'utf-8'); | |
colors = searchForColorInFile(data, filePath); | |
countAndPrintProcessedFiles(filePath, colors); | |
} else if (pType === 'DIRECTORY') { | |
processDir(filePath); | |
} else { | |
console.log(`${filePath} is not file`); | |
} | |
} | |
} | |
function countAndPrintProcessedFiles(filePath, colors) { | |
++fileCounter; | |
console.log(`${fileCounter}: ${filePath} — found ${colors.length} colors`); | |
return fileCounter; | |
} | |
function mainHandler() { | |
var start = new Date(); | |
var end, diff; | |
processDir(dirToParse); | |
printToHTMLColorMap(colorMap); | |
end = new Date(); | |
diff = end - start; | |
console.log(`Finished for ${diff}ms, found ${colorMap.size} colors`); | |
} | |
function printToHTMLColorMap(map) { | |
const header = ` | |
<!doctype html> | |
<html> | |
<head> | |
<title>${map.size} colors (${(new Date).toLocaleDateString()})</title> | |
<style> | |
body { | |
padding: 0; | |
margin: 0; | |
font-size: 0; | |
display: flex; | |
flex-flow: row wrap; | |
justify-content: center; | |
align-items: center; | |
align-content: center; | |
background: repeating-linear-gradient( 135deg, #FFF, #FFF 9px, #000 9px, #000 11px); | |
background-attachment: fixed; | |
} | |
.color b, | |
.color i { | |
pointer-events: none; | |
} | |
.color { | |
font: italic 10px/1 arial; | |
color: #333; | |
text-align: center; | |
display: flex; | |
min-width: 200px; | |
height: 40px; | |
text-shadow: 1px 0 0 #fff, -1px 0 0 #fff, 0 1px 0 #fff, 0 -1px 0 #fff; | |
flex: auto; | |
flex-flow: row wrap; | |
align-items: center; | |
justify-content: space-around; | |
align-content: center; | |
} | |
.color:hover { | |
transform: scale(1.05); | |
} | |
#modal { | |
font-size: 14px; | |
display: none; | |
position: fixed; | |
padding: 20px; | |
top: 10%; | |
left: 10%; | |
right: 10%; | |
bottom: 10%; | |
background: rgba(250,250,250,0.95); | |
overflow: auto; | |
text-shadow: 0 1px 2px #fff, 0 -1px 2px #fff; | |
} | |
#close { | |
position: absolute; | |
right: 5px; | |
top: 2px; | |
} | |
</style> | |
</head> | |
<body> | |
`; | |
const footer = ` | |
<script> | |
document.addEventListener('click', toggleModal); | |
document.addEventListener('keyup', escHandler); | |
function toggleModal(e) { | |
console.log(e); | |
var modal = document.getElementById('modal'); | |
var modalContent = document.getElementById('modal-content'); | |
var modalTitle = document.getElementById('modal-title'); | |
var target = e.target; | |
var title = target.title; | |
var bg; | |
if (target.id === 'close') { | |
modal.style.display = 'none'; | |
modal.style.background = 'rgba(250,250,250,0.95)'; | |
} else if (target.className === 'color') { | |
bg = target.style.background; | |
modalContent.innerHTML = title; | |
modal.style.display = 'block'; | |
modal.style.background = bg; | |
modal.style.boxShadow = '0 12px 110px ' + bg; | |
modalTitle.innerText = target.getElementsByTagName('b')[0].innerText; | |
} else { | |
modal.style.display = 'block'; | |
} | |
} | |
function escHandler(e) { | |
var modal = document.getElementById('modal'); | |
console.log(e); | |
if (e.keyCode === 27) { | |
modal.style.display = 'none'; | |
} | |
} | |
</script> | |
<div id="modal"> | |
<small id="close">(esc)</small> | |
<h5 id="modal-title"></h5> | |
<pre id="modal-content"></pre> | |
</div> | |
</body> | |
</html> | |
`; | |
var colors = ''; | |
var sortedColors = insertionSortForColors([...map.keys()], map); | |
sortedColors.forEach((val)=>{ | |
colors += ` | |
<div | |
class="color" | |
style="background: ${val};" | |
title="${map.get(val).place.join('\n')}"> | |
<b>${val}</b> | |
<i>${map.get(val).index}</i> | |
</div> | |
`; | |
}); | |
var data = header + colors + footer; | |
return fs.writeFileSync('colors.html', data, 'utf-8'); | |
} | |
function convertShortHEXtoLong(hex) { | |
var tmp = ''; | |
if (hex && hex.length === 4) { | |
tmp = hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3]; | |
} else if (!hex) { | |
return '#000000'; | |
} else { | |
tmp = hex; | |
} | |
return tmp; | |
} | |
function rgb2hex(rgb){ | |
rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); | |
return (rgb && rgb.length === 4) ? "#" + | |
("0" + parseInt(rgb[1],10).toString(16)).slice(-2) + | |
("0" + parseInt(rgb[2],10).toString(16)).slice(-2) + | |
("0" + parseInt(rgb[3],10).toString(16)).slice(-2) : ''; | |
} | |
/** | |
* Compare two numeric values | |
* @param a | |
* @param b | |
* @returns {boolean} | |
*/ | |
function compareTwoNumbers( a, b ) { | |
return (a - b) > 0; | |
} | |
function compareTwoColorIndex( colorA, colorB ) { | |
// console.log(`arA = ${arA}; arB = ${arB}`); | |
var indexA = colorMap.get(colorA); | |
var indexB = colorMap.get(colorB); | |
if (indexA && indexB) { | |
return (indexA.index - indexB.index) < 0; | |
} else { | |
return; | |
} | |
} | |
/** | |
* Swap tow elements in array | |
* @param arr | |
* @param posA | |
* @param posB | |
*/ | |
function swap( arr, posA, posB ) { | |
var temp = arr[posA]; | |
arr[posA] = arr[posB]; | |
arr[posB] = temp; | |
} | |
/** | |
* Returns new sorted array using Insertion Sort Algorithm | |
* @param arr | |
* @returns {Array|number} | |
*/ | |
function insertionSort( array ) { | |
var arr = array.slice(); | |
for (var i = 1; i <= arr.length; i++) { | |
var currentPos = i; | |
while (currentPos > 0 && compareTwoNumbers(parseInt(arr[currentPos - 1]), parseInt(arr[currentPos]))) { | |
swap(arr, currentPos, currentPos - 1); | |
currentPos -= 1; | |
} | |
} | |
return arr; | |
} | |
/** | |
* Returns new sorted array using Insertion Sort Algorithm | |
* @param arr | |
* @returns {Array|number} | |
*/ | |
function insertionSortForColors( array, map ) { | |
// console.log(array); | |
var arr = array.slice(); | |
for (var i = 1; i <= arr.length; i++) { | |
var currentPos = i; | |
while (currentPos > 0 && compareTwoColorIndex(arr[currentPos - 1], arr[currentPos])) { | |
swap(arr, currentPos, currentPos - 1); | |
currentPos -=1; | |
} | |
} | |
return arr; | |
} | |
function getColorIndex(color) { | |
var index, hex; | |
if (color && color[0] === '#') { | |
index = getHEXValue(color); | |
} else if (!color) { | |
return 0; | |
} else { | |
hex = rgb2hex(color); | |
index = getHEXValue(hex); | |
} | |
return index; | |
} | |
function getHEXValue(hex) { | |
var bytes = hex.slice(1); | |
var value = parseInt(bytes, 16); | |
return isNaN(value) ? 0 : value; | |
} | |
mainHandler(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment