# Usage Examples ## Basic Usage ### Parsing CSS ```javascript import { parse } from '@adobe/css-tools'; // Basic CSS parsing const css = ` body { font-size: 12px; color: #333; } .container { max-width: 1200px; margin: 0 auto; } `; const ast = parse(css); console.log(ast); ``` ### Stringifying AST ```javascript import { parse, stringify } from '@adobe/css-tools'; const css = 'body { font-size: 12px; color: #333; }'; const ast = parse(css); // Convert back to CSS const output = stringify(ast); console.log(output); // "body { font-size: 12px; color: #333; }" ``` ## Advanced Parsing Options ### Source Tracking ```javascript import { parse } from '@adobe/css-tools'; const css = 'body { color: red; }'; const ast = parse(css, { source: 'styles.css' }); // Position information is available const rule = ast.stylesheet.rules[0]; console.log(rule.position?.source); // "styles.css" console.log(rule.position?.start); // { line: 1, column: 1 } console.log(rule.position?.end); // { line: 1, column: 20 } ``` ### Silent Error Handling ```javascript import { parse } from '@adobe/css-tools'; const malformedCss = ` body { color: red; } { color: blue; } /* Missing selector */ .valid { background: green; } `; // Parse with silent error handling const result = parse(malformedCss, { silent: true }); // Check for parsing errors if (result.stylesheet.parsingErrors) { console.log('Parsing errors:', result.stylesheet.parsingErrors.length); result.stylesheet.parsingErrors.forEach(error => { console.log(`Error at line ${error.line}: ${error.message}`); }); } // Valid rules are still parsed console.log('Valid rules:', result.stylesheet.rules.length); ``` ## AST Structure Examples ### Basic Rule ```javascript import { parse } from '@adobe/css-tools'; const css = ` .header { background: #f0f0f0; padding: 20px; border-bottom: 1px solid #ccc; } `; const ast = parse(css); const rule = ast.stylesheet.rules[0]; console.log(rule.type); // "rule" console.log(rule.selectors); // [".header"] console.log(rule.declarations.length); // 3 rule.declarations.forEach(decl => { console.log(`${decl.property}: ${decl.value}`); }); // Output: // background: #f0f0f0 // padding: 20px // border-bottom: 1px solid #ccc ``` ### Media Queries ```javascript import { parse } from '@adobe/css-tools'; const css = ` @media screen and (max-width: 768px) { .container { padding: 10px; } .sidebar { display: none; } } `; const ast = parse(css); const mediaRule = ast.stylesheet.rules[0]; console.log(mediaRule.type); // "media" console.log(mediaRule.media); // "screen and (max-width: 768px)" console.log(mediaRule.rules.length); // 2 ``` ### Keyframes ```javascript import { parse } from '@adobe/css-tools'; const css = ` @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } `; const ast = parse(css); const keyframesRule = ast.stylesheet.rules[0]; console.log(keyframesRule.type); // "keyframes" console.log(keyframesRule.name); // "fadeIn" console.log(keyframesRule.keyframes.length); // 2 keyframesRule.keyframes.forEach(keyframe => { console.log(`Keyframe: ${keyframe.values.join(', ')}`); keyframe.declarations.forEach(decl => { console.log(` ${decl.property}: ${decl.value}`); }); }); ``` ### Comments ```javascript import { parse } from '@adobe/css-tools'; const css = ` /* Header styles */ .header { background: red; /* Fallback color */ } /* Footer styles */ .footer { background: blue; } `; const ast = parse(css); ast.stylesheet.rules.forEach(rule => { if (rule.type === 'comment') { console.log(`Comment: ${rule.comment}`); } else if (rule.type === 'rule') { console.log(`Rule: ${rule.selectors.join(', ')}`); rule.declarations.forEach(decl => { if (decl.type === 'comment') { console.log(` Comment: ${decl.comment}`); } else { console.log(` ${decl.property}: ${decl.value}`); } }); } }); ``` ## Stringifying Options ### Compressed Output ```javascript import { parse, stringify } from '@adobe/css-tools'; const css = ` body { font-size: 12px; color: #333; margin: 0; padding: 0; } `; const ast = parse(css); // Compressed output const compressed = stringify(ast, { compress: true }); console.log(compressed); // Output: "body{font-size:12px;color:#333;margin:0;padding:0}" ``` ### Custom Indentation ```javascript import { parse, stringify } from '@adobe/css-tools'; const css = 'body { font-size: 12px; color: #333; }'; const ast = parse(css); // Custom indentation const formatted = stringify(ast, { indent: ' ' }); console.log(formatted); // Output: // body { // font-size: 12px; // color: #333; // } ``` ## Working with Complex CSS ### Nested Rules and At-Rules ```javascript import { parse, stringify } from '@adobe/css-tools'; const complexCss = ` @import url('https://fonts.googleapis.com/css2?family=Roboto'); @charset "UTF-8"; @media print { body { font-size: 12pt; } } @supports (display: grid) { .grid { display: grid; } } @keyframes slideIn { 0% { transform: translateX(-100%); } 100% { transform: translateX(0); } } @font-face { font-family: 'CustomFont'; src: url('custom-font.woff2') format('woff2'); } `; const ast = parse(complexCss); ast.stylesheet.rules.forEach(rule => { switch (rule.type) { case 'import': console.log(`Import: ${rule.import}`); break; case 'charset': console.log(`Charset: ${rule.charset}`); break; case 'media': console.log(`Media query: ${rule.media}`); break; case 'supports': console.log(`Supports: ${rule.supports}`); break; case 'keyframes': console.log(`Keyframes: ${rule.name}`); break; case 'font-face': console.log('Font-face rule'); break; } }); ``` ### Manipulating the AST ```javascript import { parse, stringify } from '@adobe/css-tools'; const css = ` .button { background: blue; color: white; padding: 10px; } `; const ast = parse(css); const rule = ast.stylesheet.rules[0]; // Add a new declaration rule.declarations.push({ type: 'declaration', property: 'border-radius', value: '5px' }); // Modify existing declaration const backgroundDecl = rule.declarations.find(d => d.property === 'background'); if (backgroundDecl) { backgroundDecl.value = 'red'; } // Add a new selector rule.selectors.push('.btn'); const modifiedCss = stringify(ast); console.log(modifiedCss); ``` ## Error Handling ### Catching Parse Errors ```javascript import { parse, CssParseError } from '@adobe/css-tools'; try { const ast = parse('body { color: red; } { invalid }'); } catch (error) { if (error instanceof CssParseError) { console.log(`Parse error at line ${error.line}, column ${error.column}:`); console.log(error.message); console.log(`Source: ${error.filename}`); } } ``` ### Working with Silent Errors ```javascript import { parse } from '@adobe/css-tools'; const problematicCss = ` body { color: red; } { color: blue; } /* Missing selector */ .valid { background: green; } .another { border: 1px solid; } /* Missing closing brace */ `; const result = parse(problematicCss, { silent: true, source: 'problematic.css' }); // Process valid rules const validRules = result.stylesheet.rules.filter(rule => rule.type === 'rule'); console.log(`Found ${validRules.length} valid rules`); // Log errors for debugging if (result.stylesheet.parsingErrors) { result.stylesheet.parsingErrors.forEach(error => { console.log(`Error: ${error.message} at line ${error.line}`); }); } ``` ### CSS Minification ```javascript import { parse, stringify } from '@adobe/css-tools'; function minifyCSS(css) { const ast = parse(css); return stringify(ast, { compress: true }); } const css = ` body { font-size: 12px; color: #333; margin: 0; padding: 0; } .container { max-width: 1200px; margin: 0 auto; } `; const minified = minifyCSS(css); console.log(minified); // Output: "body{font-size:12px;color:#333;margin:0;padding:0}.container{max-width:1200px;margin:0 auto}" ``` ### CSS Validation ```javascript import { parse } from '@adobe/css-tools'; function validateCSS(css, filename = 'unknown') { try { const ast = parse(css, { source: filename }); return { valid: true, rules: ast.stylesheet.rules.length, errors: [] }; } catch (error) { return { valid: false, rules: 0, errors: [{ message: error.message, line: error.line, column: error.column, source: error.filename }] }; } } const result = validateCSS('body { color: red; } { invalid }', 'test.css'); console.log(result); ```