Skip to content

Instantly share code, notes, and snippets.

@rmbrntt
Last active March 23, 2023 23:47
Show Gist options
  • Save rmbrntt/40100513623f3b3f0ef882125be83fe6 to your computer and use it in GitHub Desktop.
Save rmbrntt/40100513623f3b3f0ef882125be83fe6 to your computer and use it in GitHub Desktop.
function cssToJson(css) {
const json = {};
const rules = css.replace(/\/\*[\s\S]*?\*\//g, '') // remove comments
.split('}');
for (let i = 0; i < rules.length - 1; i++) {
const rule = rules[i].split('{');
const selector = rule[0].trim();
const properties = rule[1].split(';');
const selectorObject = {};
for (let j = 0; j < properties.length - 1; j++) {
const property = properties[j].split(':');
const propertyName = property[0].trim();
const propertyValue = property[1].trim().replace(/['"]/g, ''); // remove quotes
if (propertyName.startsWith('-')) {
const unprefixedPropertyName = propertyName.substr(propertyName.indexOf('-') + 1);
if (!selectorObject[unprefixedPropertyName]) {
selectorObject[unprefixedPropertyName] = propertyValue;
}
} else {
selectorObject[propertyName] = propertyValue;
}
}
const selectors = selector.split(',').map(s => s.trim()); // handle multiple selectors
selectors.forEach(s => {
if (!json[s]) {
json[s] = {};
}
Object.assign(json[s], selectorObject);
});
}
return json;
}
function jsonToCss(json) {
let css = "";
for (let selector in json) {
if (selector.startsWith('@')) {
// handle media queries
css += selector + " {\n" + jsonToCss(json[selector]) + "}\n";
} else {
css += selector + " {\n";
for (let property in json[selector]) {
const value = json[selector][property];
if (value !== "") { // handle empty values
if (property.startsWith('-')) {
const prefixedProperty = '-' + selector.split('-')[0] + '-' + property.substr(1);
css += " " + prefixedProperty + ": " + value + ";\n";
}
css += " " + property + ": " + value + ";\n";
}
}
css += "}\n";
}
}
return css;
}
function cssToJson(css) {
const json = {};
const rules = css.split('}');
for (let i = 0; i < rules.length - 1; i++) {
const rule = rules[i].split('{');
const selector = rule[0].trim();
const properties = rule[1].split(';');
const selectorObject = {};
for (let j = 0; j < properties.length - 1; j++) {
const property = properties[j].split(':');
const propertyName = property[0].trim();
const propertyValue = property[1].trim();
selectorObject[propertyName] = propertyValue;
}
json[selector] = selectorObject;
}
return json;
}
function jsonToCss(json) {
let css = "";
for (let selector in json) {
css += selector + " {\n";
for (let property in json[selector]) {
css += " " + property + ": " + json[selector][property] + ";\n";
}
css += "}\n";
}
return css;
}
function scssToJson(scss) {
const json = {};
const lines = scss.split('\n');
let currentSelector = '';
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (line === '') {
continue;
}
if (line.startsWith('//')) {
continue;
}
if (line.startsWith('$')) {
continue;
}
if (line.startsWith('@media')) {
const nestedJson = scssToJson(lines.slice(i + 1).join('\n'));
if (!json[line]) {
json[line] = {};
}
Object.assign(json[line], nestedJson);
break;
}
if (line.startsWith('@')) {
continue;
}
if (line.endsWith('{')) {
currentSelector = line.replace('{', '').trim();
if (!json[currentSelector]) {
json[currentSelector] = {};
}
continue;
}
if (line.endsWith('}')) {
currentSelector = '';
continue;
}
const parts = line.split(':');
const propertyName = parts[0].trim();
const propertyValue = parts[1].replace(/!default|!important|;/g, '').trim();
if (!json[currentSelector]) {
json[currentSelector] = {};
}
json[currentSelector][propertyName] = propertyValue;
}
return json;
}
function jsonToScss(json, indent = '') {
let scss = '';
for (let selector in json) {
if (selector.startsWith('@media')) {
scss += selector + ' {\n';
scss += jsonToScss(json[selector], ' ');
scss += '}\n';
} else {
scss += indent + selector + ' {\n';
for (let property in json[selector]) {
scss += indent + ' ' + property + ': ' + json[selector][property] + ';\n';
}
scss += indent + '}\n';
}
}
return scss;
}
body {
background-color: #F5F5F5;
font-family: Arial, sans-serif;
}
header {
background-color: #333333;
color: #FFFFFF;
padding: 20px;
}
nav {
background-color: #666666;
color: #FFFFFF;
padding: 10px;
}
a {
color: #0000FF;
text-decoration: none;
transition: color 0.2s ease-in-out;
}
a:hover {
color: #FF0000;
}
{
"body": {
"background-color": "#F5F5F5",
"font-family": "Arial, sans-serif"
},
"header": {
"background-color": "#333333",
"color": "#FFFFFF",
"padding": "20px"
},
"nav": {
"background-color": "#666666",
"color": "#FFFFFF",
"padding": "10px"
},
"a": {
"color": "#0000FF",
"text-decoration": "none",
"transition": "color 0.2s ease-in-out"
},
"a:hover": {
"color": "#FF0000"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment