1<?php
2
3namespace LesserPHP\Functions;
4
5use Exception;
6use LesserPHP\Utils\Color;
7use LesserPHP\Utils\Util;
8
9/**
10 * Implements the string functions for LESS
11 *
12 * @link https://lesscss.org/functions/#string-functions
13 */
14class Strings extends AbstractFunctionCollection
15{
16    /** @inheritdoc */
17    public function getFunctions(): array
18    {
19        return [
20            //'escape' => [$this, 'escape'],
21            'e' => [$this, 'e'],
22            '%' => [$this, 'format'],
23            //'replace' => [$this, 'replace'],
24        ];
25    }
26
27
28    // escape is missing
29
30    /**
31     * String escaping.
32     *
33     * It expects string as a parameter and return its content as is, but without quotes. It can be used
34     * to output CSS value which is either not valid CSS syntax, or uses proprietary syntax which
35     * Less doesn't recognize.
36     *
37     * @link https://lesscss.org/functions/#string-functions-e
38     * @throws Exception
39     */
40    public function e(array $arg): array
41    {
42        return $this->lessc->unwrap($arg);
43    }
44
45    /**
46     * Formats a string
47     *
48     * @link https://lesscss.org/functions/#string-functions--format
49     * @throws Exception
50     */
51    public function format(array $args) : array
52    {
53        if ($args[0] != 'list') return $args;
54        $values = $args[2];
55        $string = array_shift($values);
56        $template = $this->lessc->compileValue($this->lessc->unwrap($string));
57
58        $i = 0;
59        if (preg_match_all('/%[dsa]/', $template, $m)) {
60            foreach ($m[0] as $match) {
61                $val = isset($values[$i]) ?
62                    $this->lessc->reduce($values[$i]) : ['keyword', ''];
63
64                // lessjs compat, renders fully expanded color, not raw color
65                if ($color = Color::coerceColor($val)) {
66                    $val = $color;
67                }
68
69                $i++;
70                $rep = $this->lessc->compileValue($this->lessc->unwrap($val));
71                $template = preg_replace(
72                    '/' . Util::pregQuote($match) . '/',
73                    $rep,
74                    $template,
75                    1
76                );
77            }
78        }
79
80        $d = $string[0] == 'string' ? $string[1] : '"';
81        return ['string', $d, [$template]];
82    }
83
84    // replace is missing
85}
86