parseColors(); if (!$colors) { return ['#markup' => \Drupal\Core\Render\Markup::create('

Could not parse tailwind.config.js

')]; } $html = '
'; foreach ($colors as $group => $shades) { $html .= '
' . htmlspecialchars($group) . '
'; $html .= '
'; foreach ($shades as $shade => $hex) { $label = $shade === 'DEFAULT' ? $group : "$group-$shade"; $border = $this->luminance($hex) > 200 ? 'border:1px solid #ddd;' : ''; $html .= '
' . "
" . '
' . '
' . htmlspecialchars($label) . '
' . '
' . htmlspecialchars($hex) . '
' . '
' . '
'; } $html .= '
'; } $html .= '
'; return ['#markup' => \Drupal\Core\Render\Markup::create($html)]; } private function parseColors(): array { $path = dirname(DRUPAL_ROOT) . '/tailwind.config.js'; if (!file_exists($path)) { return []; } $content = file_get_contents($path); // Find the opening of the colors: { block if (!preg_match('/colors\s*:\s*\{/', $content, $m, PREG_OFFSET_CAPTURE)) { return []; } $start = $m[0][1] + strlen($m[0][0]); // Walk forward counting braces to find the closing } $depth = 1; $i = $start; $len = strlen($content); while ($i < $len && $depth > 0) { if ($content[$i] === '{') $depth++; elseif ($content[$i] === '}') $depth--; $i++; } $block = substr($content, $start, $i - $start - 1); $colors = []; // 'group': { shade: '#hex', ... } preg_match_all("/'([^']+)'\s*:\s*\{([^}]+)\}/", $block, $groups, PREG_SET_ORDER); foreach ($groups as $group) { $name = $group[1]; preg_match_all('/(\w+)\s*:\s*\'(#[0-9a-fA-F]{3,6})\'/', $group[2], $shades, PREG_SET_ORDER); foreach ($shades as $shade) { $colors[$name][$shade[1]] = $shade[2]; } } // 'group': '#hex' (flat single-value entry) preg_match_all("/'([^']+)'\s*:\s*'(#[0-9a-fA-F]{3,6})'/", $block, $singles, PREG_SET_ORDER); foreach ($singles as $single) { if (!isset($colors[$single[1]])) { $colors[$single[1]]['DEFAULT'] = $single[2]; } } return $colors; } private function luminance(string $hex): int { $hex = ltrim($hex, '#'); return (int) ( 0.299 * hexdec(substr($hex, 0, 2)) + 0.587 * hexdec(substr($hex, 2, 2)) + 0.114 * hexdec(substr($hex, 4, 2)) ); } }