parseModelColor function
Parses an xcolor model specification: \color[rgb]{0.1,0.2,0.3}.
Supported models: rgb (0–1), RGB (0–255), HTML (hex), gray
(0–1), cmyk (0–1). Returns null if the value is invalid.
Implementation
LatexColor? parseModelColor(String model, String value) {
final parts = value.split(',').map((s) => s.trim()).toList();
double? unit(String s) {
final v = double.tryParse(s);
return v == null || v < 0 || v > 1 ? null : v;
}
int byte(double v) => (v * 255).round();
switch (model) {
case 'rgb':
if (parts.length != 3) return null;
final c = parts.map(unit).toList();
if (c.contains(null)) return null;
return LatexColor.fromARGB(0xFF, byte(c[0]!), byte(c[1]!), byte(c[2]!));
case 'RGB':
if (parts.length != 3) return null;
final c = parts.map(int.tryParse).toList();
if (c.any((v) => v == null || v < 0 || v > 255)) return null;
return LatexColor.fromARGB(0xFF, c[0]!, c[1]!, c[2]!);
case 'HTML':
if (!RegExp(r'^[0-9a-fA-F]{6}$').hasMatch(value.trim())) return null;
return LatexColor(0xFF000000 | int.parse(value.trim(), radix: 16));
case 'gray':
if (parts.length != 1) return null;
final g = unit(parts[0]);
if (g == null) return null;
return LatexColor.fromARGB(0xFF, byte(g), byte(g), byte(g));
case 'cmyk':
if (parts.length != 4) return null;
final c = parts.map(unit).toList();
if (c.contains(null)) return null;
final k = c[3]!;
int channel(double v) => byte((1 - v) * (1 - k));
return LatexColor.fromARGB(
0xFF,
channel(c[0]!),
channel(c[1]!),
channel(c[2]!),
);
}
return null;
}