extractTokens method

Map<String, String> extractTokens(
  1. String propertyPrefix,
  2. String conversionType
)

Extract tokens by property prefix

Implementation

Map<String, String> extractTokens(
  String propertyPrefix,
  String conversionType,
) {
  final tokens = <String, String>{};

  // Create regex pattern for the property
  RegExp regex;
  if (propertyPrefix == 'spacing') {
    // Handle spacing without suffix (--spacing: value)
    regex = RegExp('--spacing:\\s*([^;]+);', multiLine: true, dotAll: true);
  } else if (propertyPrefix == 'color') {
    // Handle color tokens (--color-red-500: #ef4444;)
    regex = RegExp(
      '--color-([^:]+):\\s*([^;]+);',
      multiLine: true,
      dotAll: true,
    );
  } else if (propertyPrefix == 'text-style') {
    // Handle text-style tokens by combining text size and line height
    return _extractTextStyleTokens();
  } else if (propertyPrefix == 'aspect-video') {
    // Handle aspect-video token (--aspect-video: 16 / 9;)
    regex = RegExp(
      '--aspect-video:\\s*([^;]+);',
      multiLine: true,
      dotAll: true,
    );
  } else if (propertyPrefix == 'text') {
    // Handle text tokens (--text-xs: 0.75rem;) but exclude line-height variables
    regex = RegExp(
      '--text-([^:]+):\\s*([^;]+);',
      multiLine: true,
      dotAll: true,
    );
  } else if (propertyPrefix == 'font') {
    // Only capture the canonical stacks: --font-sans, --font-serif, --font-mono
    regex = RegExp(
      '--font-(sans|serif|mono):\\s*([^;]+);',
      multiLine: true,
      dotAll: true,
    );
  } else {
    regex = RegExp(
      '--$propertyPrefix-([^:]+):\\s*([^;]+);',
      multiLine: true,
      dotAll: true,
    );
  }
  final matches = regex.allMatches(cssContent);

  for (final match in matches) {
    // Skip line-height variables when extracting text tokens
    if (propertyPrefix == 'text' &&
        match.group(1)!.contains('--line-height')) {
      continue;
    }
    String tokenName;
    String tokenValue;

    if (propertyPrefix == 'spacing') {
      // For spacing, there's no token name, just use 'base' as the default
      tokenName = 'base';
      tokenValue = match.group(1)!.trim().replaceAll(RegExp(r'\s+'), ' ');
    } else if (propertyPrefix == 'aspect-video') {
      // For aspect-video, there's no token name, just use 'base' as the default
      tokenName = 'base';
      tokenValue = match.group(1)!.trim().replaceAll(RegExp(r'\s+'), ' ');
    } else if (propertyPrefix == 'font') {
      // Regex ensures name is one of: sans | serif | mono
      tokenName = match.group(1)!.trim();
      tokenValue = match.group(2)!.trim().replaceAll(RegExp(r'\s+'), ' ');
    } else {
      tokenName = match.group(1)!.trim();
      tokenValue = match.group(2)!.trim().replaceAll(RegExp(r'\s+'), ' ');
    }

    try {
      String flutterValue = _convertValue(tokenValue, conversionType);
      String cleanName = _cleanTokenName(tokenName);
      tokens[cleanName] = flutterValue;
    } catch (e) {
      print(
        'Warning: Could not convert $propertyPrefix $tokenName ($tokenValue): $e',
      );
    }
  }

  // For spacing, always include default values
  if (propertyPrefix == 'spacing') {
    final defaultSpacing = _getDefaultSpacingValues();
    // Merge default values, but don't override existing ones from theme
    for (final entry in defaultSpacing.entries) {
      if (!tokens.containsKey(entry.key)) {
        tokens[entry.key] = entry.value;
      }
    }
  }

  // For font, always include default values
  if (propertyPrefix == 'font') {
    final defaultFonts = _getDefaultFontValues();
    // Merge default values, but don't override existing ones from theme
    for (final entry in defaultFonts.entries) {
      if (!tokens.containsKey(entry.key)) {
        tokens[entry.key] = entry.value;
      }
    }
  }

  return tokens;
}