sass-export
Version:
Exports Sass files to Json format, able to manage sections with annotations in comments.
117 lines • 4.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Parser = void 0;
const VARIABLE_PATERN = '(?!\\d)[\\w_-][\\w\\d_-]*';
const MAP_KEY_PATTERN = '[\\w-]+';
const VALUE_PATERN = '[^;]+|"(?:[^"]+|(?:\\\\"|[^"])*)"';
const MAP_DECLARATIOM_REGEX = /['"]?([\w_-][\w\d_-]*)['"]?\s*:\s*([a-z\-]+\([^\)]+\)|[^\)\(,\/]+|\([^\)]+\))/gi;
const QUOTES_PATTERN = /^(['"]).*\1$/;
const QUOTES_REPLACE = /^(['"])|(['"])$/g;
const SECTION_TAG = 'sass-export-section';
const SECTION_PATTERN = `(@${SECTION_TAG}=)(".+")`;
const END_SECTION_PATTERN = `(@end-${SECTION_TAG})`;
const DEFAULT_SECTION = 'variables';
class Parser {
constructor(rawContent) {
this.rawContent = rawContent;
}
parse() {
let matches = this.extractDeclarations(this.rawContent);
let declarations = [];
for (let match of matches) {
if (!this.checkIsSectionStart(match) && !this.checkIsSectionStart(match)) {
let parsed = this.parseSingleDeclaration(match);
if (parsed) {
this.parseMapDeclarations(parsed);
declarations.push(parsed);
}
}
}
return declarations;
}
parseStructured() {
let matches = this.extractDeclarationsStructured(this.rawContent);
let currentSection = DEFAULT_SECTION;
let declarations = {};
if (!matches || !matches.length) {
return {};
}
declarations[currentSection] = [];
for (let match of matches) {
if (this.checkIsSectionStart(match)) {
let sectionName = String(new RegExp(SECTION_PATTERN, 'gi').exec(match)[2]);
if (sectionName) {
currentSection = sectionName.replace(/"/g, '');
declarations[currentSection] = declarations[currentSection] || [];
}
}
else if (this.checkIsSectionEnd(match)) {
currentSection = DEFAULT_SECTION;
}
else {
let parsed = this.parseSingleDeclaration(match);
if (parsed) {
this.parseMapDeclarations(parsed);
declarations[currentSection].push(parsed);
}
}
}
return declarations;
}
extractDeclarationsStructured(content) {
const matches = content.match(new RegExp(`${this.getDeclarationPattern()}|${SECTION_PATTERN}|${END_SECTION_PATTERN}`, 'g'));
if (!matches) {
return [];
}
return matches;
}
extractDeclarations(content) {
const matches = content.match(new RegExp(this.getDeclarationPattern(), 'g'));
if (!matches) {
return [];
}
return matches;
}
extractMapDeclarations(content) {
const matches = content.match(new RegExp(MAP_DECLARATIOM_REGEX, 'g'));
if (!matches) {
return [];
}
return matches;
}
parseSingleDeclaration(matchDeclaration, isMap = false) {
let matches = matchDeclaration
.replace(/\s*!(default|global)\s*;/, ';')
.match(new RegExp(this.getDeclarationPattern(isMap)));
if (!matches) {
return;
}
let name = matches[1].trim();
let value = matches[2].trim().replace(/\s*\n+\s*/g, ' ');
if (value.match(QUOTES_PATTERN)) {
value = value.replace(QUOTES_REPLACE, '');
}
return { name, value };
}
parseMapDeclarations(parsedDeclaration) {
let map = this.extractMapDeclarations(parsedDeclaration.value);
if (map.length) {
parsedDeclaration.mapValue = map.map((declaration) => {
const singleDeclaration = this.parseSingleDeclaration(`$${declaration};`, true);
this.parseMapDeclarations(singleDeclaration);
return singleDeclaration;
});
}
}
checkIsSectionStart(content) {
return (new RegExp(SECTION_PATTERN, 'gi')).test(content);
}
checkIsSectionEnd(content) {
return (new RegExp(END_SECTION_PATTERN, 'gi')).test(content);
}
getDeclarationPattern(isMap = false) {
return `\\$['"]?(${isMap ? MAP_KEY_PATTERN : VARIABLE_PATERN})['"]?\\s*:\\s*(${VALUE_PATERN})(?:\\s*!(global|default)\\s*;|\\s*;(?![^\\{]*\\}))`;
}
}
exports.Parser = Parser;
//# sourceMappingURL=parser.js.map