protected static function convertNthExpression($expression)
{
if ($expression === '') {
throw new RuntimeException('Invalid selector: nth-child (or nth-last-child) expression must not be empty');
}
if ($expression === 'odd') {
return 'position() mod 2 = 1 and position() >= 1';
}
if ($expression === 'even') {
return 'position() mod 2 = 0 and position() >= 0';
}
if (is_numeric($expression)) {
return sprintf('position() = %d', $expression);
}
if (preg_match("/^(?P<mul>[0-9]?n)(?:(?P<sign>\\+|\\-)(?P<pos>[0-9]+))?\$/is", $expression, $segments)) {
if (isset($segments['mul'])) {
$multiplier = $segments['mul'] === 'n' ? 1 : trim($segments['mul'], 'n');
$sign = (isset($segments['sign']) and $segments['sign'] === '+') ? '-' : '+';
$position = isset($segments['pos']) ? $segments['pos'] : 0;
return sprintf('(position() %s %d) mod %d = 0 and position() >= %d', $sign, $position, $multiplier, $position);
}
}
throw new RuntimeException('Invalid selector: invalid nth-child expression');
}