1<?php
2/**
3 * http://leafo.net/lessphp
4 *
5 * LESS CSS compiler, adapted from http://lesscss.org
6 *
7 * Copyright 2013, Leaf Corcoran <leafot@gmail.com>
8 * Copyright 2016, Marcus Schwarz <github@maswaba.de>
9 * Licensed under MIT or GPLv3, see LICENSE
10 */
11
12
13namespace LesserPHP;
14
15class FormatterClassic
16{
17    public $indentChar = '  ';
18
19    public $break = "\n";
20    public $open = ' {';
21    public $close = '}';
22    public $selectorSeparator = ', ';
23    public $assignSeparator = ':';
24
25    public $openSingle = ' { ';
26    public $closeSingle = ' }';
27
28    public $disableSingle = false;
29    public $breakSelectors = false;
30
31    public $compressColors = false;
32    protected int $indentLevel;
33
34    public function __construct()
35    {
36        $this->indentLevel = 0;
37    }
38
39    public function indentStr($n = 0)
40    {
41        return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
42    }
43
44    public function property($name, $value)
45    {
46        return $name . $this->assignSeparator . $value . ';';
47    }
48
49    protected function isEmpty($block)
50    {
51        if (empty($block->lines)) {
52            foreach ($block->children as $child) {
53                if (!$this->isEmpty($child)) return false;
54            }
55
56            return true;
57        }
58        return false;
59    }
60
61    public function block($block)
62    {
63        if ($this->isEmpty($block)) return;
64
65        $inner = $pre = $this->indentStr();
66
67        $isSingle = !$this->disableSingle &&
68            is_null($block->type) && count($block->lines) == 1;
69
70        if (!empty($block->selectors)) {
71            $this->indentLevel++;
72
73            if ($this->breakSelectors) {
74                $selectorSeparator = $this->selectorSeparator . $this->break . $pre;
75            } else {
76                $selectorSeparator = $this->selectorSeparator;
77            }
78
79            echo $pre .
80                implode($selectorSeparator, $block->selectors);
81            if ($isSingle) {
82                echo $this->openSingle;
83                $inner = '';
84            } else {
85                echo $this->open . $this->break;
86                $inner = $this->indentStr();
87            }
88        }
89
90        if (!empty($block->lines)) {
91            $glue = $this->break . $inner;
92            echo $inner . implode($glue, $block->lines);
93            if (!$isSingle && !empty($block->children)) {
94                echo $this->break;
95            }
96        }
97
98        foreach ($block->children as $child) {
99            $this->block($child);
100        }
101
102        if (!empty($block->selectors)) {
103            if (!$isSingle && empty($block->children)) echo $this->break;
104
105            if ($isSingle) {
106                echo $this->closeSingle . $this->break;
107            } else {
108                echo $pre . $this->close . $this->break;
109            }
110
111            $this->indentLevel--;
112        }
113    }
114}
115