UNPKG

sass-export

Version:

Exports Sass files to Json format, able to manage sections with annotations in comments.

117 lines 4.48 kB
"use strict"; 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