css-parser-ecss

Gesponsorde koppelingen

PHP script bestanden

  1. css-parser-ecss

« Lees de omschrijving en reacties

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
<?php

/** CSS parser class
  * used to parse normal css
  * @author         Ruud Verbij
  * @start_date     4 Oct 2007
  * @version         0.1a
  * @documentation    www.ruudverbij.nl/css/documentation.doc (very little)
  */


class CSSParser {

    // Class instance variables
    /*  Array with names of the css files to be parsed
      * initiated by the constructor and files added by addCSSFile()
      * @invariant cssNames != null && count(cssNames) > 0
      */

    private $cssNames = Array();

    /*  Array with content of the css files to be parsed (raw)
      * iniated by the constructor and updated by addCSSFile()
      * @invariant cssContents != null && count(cssContents) > 0
      */

    private $cssContents = Array();

    /*  Boolean that says if the output should be combined
      * if set true; setCombinedFileName() should be called
      * iniated by the constructor or updated by setCombinedFileName()
      * @invariant if(combined) getCombinedFileName != null
      */

    private $combine;

    /*  String containing the filename for the output if combine is set true
      * @invariant if(getCombined() == true) combinedFileName != null
      */

    private $combinedFileName = null;

    /*  Boolean that says if the parser should delete comments
      * initiated by the constructor and updated by cutComments()
      */

    private $cutComments;


    // Class constructor
    /** Constructor used for getting an instance of this class
      * @param Array - contains all files to be parsed (numeric)
      * @param Boolean - says if the fileoutput should be combined
      * @param Boolean - says if the parser should cut out comments
      * @require setCombinedFileName() must be called if combine is set true
      * @require count(files) > 0
      * @require file_exists(each file from $files)
      * @ensure getFileNames() == files
      * @ensure getCombined() == combine
      */

    public function __construct($files,$combine = false, $cutComments = true) {
        // set all instance variables
        $this->cssNames    = $files;
        $this->combine     = $combine;
        $this->cutComments = $cutComments;

        // get content from filenames and place them in the instance variable
        for($i = 0; $i < count($this->getFileNames()); $i++) {
            $this->cssContents[$i] = file_get_contents($this->cssNames[$i]);
        }
    }



    // Query functions
    /** function to check if combined has been set true
      * @return Boolean
      */

    public function getCombined() {
        return $this->combine;
    }


    /** function to check the filename of the combinedFileName
      * @return String or NULL
      */

    public function getCombinedFileName() {
        return $this->combinedFileName;
    }


    /** function to get all filenames that will be parsed
      * @return Array
      */

    public function getFileNames() {
        return $this->cssNames;
    }


    /** function to check if the parser will cut out comments
      * @return Boolean
      */

    public function getCutComments() {
        return $this->cutComments;
    }



    // Command functions
    /** function to set the combinedFileName
      * @param String
      * @ensure getCombined() == true
      * @ensure getCombinedFileName() == $filename
      */

    public function setCombinedFileName($filename) {
        $this->combine = true;
        $this->combinedFileName = (substr($filename,strlen($filename)-3) == 'css') ? substr($filename,0,strlen($filename)-1) : $filename;
    }


    /** function to add a cssfile that needs to be parsed
      * @param String
      * @ensure getFileNames()[i] == $filename
      */

    public function addCSSFile($filename) {
        $this->cssNames[] = $filename;
        $this->cssContents[] = file_get_contents($filename);
    }


    /** function to set the parser to cut comments or not
      * @param Boolean
      */

    public function setCutComments($cutComments) {
        $this->cutComments = $cutComments;
    }



    // Class functions
    /** function to parse the files added by addCSSFile and the constructor
      * @ensure if(getCombined()) then getCombinedFileName() contains all parsed css
      *         else getFileNames()[i] contains parsed css for file_get_contents(getFileNames()[i])
      */

    public function parseFiles() {
        $this->writeOutput($this->parse());
    }

    
    /*  function to write all output
      * @param Array - containing arrays per file (numeric) and per file (characters) 'css' and 'filename'
      * @ensure files will be written
      */

    private function writeOutput($output) {
        // then you can combine them
        if($this->getCombined()) {
            // combine all css
            $sub_output;
            for($i = 0; $i < count($output); $i++) {
                $sub_output .= '\n' . $output[$i]['css'];
            }


            // write sub_output to the getCombinedFileName() and build the file if it does not exists
            $handle = fopen($this->getCombinedFileName(), 'w');
            fwrite($handle, $sub_output);
            fclose($handle);
        }
else {
            // write output to each file
            for($i = 0; $i < count($output); $i++) {
                $handle = fopen($output[$i]['filename'], 'w');
                fwrite($handle, $output[$i]['css']);
                fclose($handle);
            }
        }
    }

    
    /** echo the parsed files */
    public function echoParsedFiles() {
        $output = $this->parse();
        $sub_output;
        for($i = 0; $i < count($output); $i++) {
            $sub_output .= $output[$i]['css'];
        }

        echo $sub_output;
    }

    
    /* parse the filenames as prepared */
    private function parse() {
        $output = array();

        // first parse all files seperate
        for($i = 0; $i < count($this->getFileNames()); $i++) {
            $filenames = $this->getFileNames();
            $contents  = $this->cssContents[$i];
            $css = $this->splitFile($contents);
            $sub_output = ($this->getCutComments()) ? $this->cutComments($css[1]) : $css[1];
            $sub_output = $this->extendClasses($css[0],$sub_output);
            $sub_output = $this->parseVariables($css[0],$sub_output);
            $output[] = array('css'=> $sub_output,'filename'=>substr($filenames[$i],0,strlen($filenames[$i])-1));
        }

        
        return $output;
    }


    /*  function to split the file in 2 parts: the extended part and the actual css part
      * @param String - file to be split
      * @require $file != null
      * @return Array - return[0] = extended, return[1] = actual
    */

    static private function splitFile($file) {
        $filebrokencontent = preg_split('/\*\*\*[\s]?(ACTUAL|EXTENDED)[\s]?CSS[\s]?\*\*\*/i',$file);
        return array($filebrokencontent[1],$filebrokencontent[2]);
    }


    /*  function to cut out comments
      * @param String - containing the actual-part of the css file where comments should be cut out
      * @require $actual != null
      * @ensure return does not contain css-comments
      * @return String - the actual-css part without comments
      */

    static private function cutComments($actual) {
        return preg_replace('/\/\\*.*\*\//s','',$actual);
    }


    /*  function to parse variables declared in the extended part within the actual part
      * @param String - the extended part of the css
      * @param String - the actual part of the css
      * @require ($extended && $actual) != null
      * @return String - the actual part of the css file parsed with the variables declared in the extended part
      */

    static private function parseVariables($extended,$actual) {
        preg_match_all('/(\$[a-zA-Z]+[a-zA-Z0-9_]*)[\s]*:[\s]*([#0-9a-zA-Z\']+)/',$extended,$matches);
        $variables = $matches[1];
        $variables_content = $matches[2];
        for($i = 0; $i < count($variables); $i++)
            $actual = preg_replace('/\\'.$variables[$i].'/i',$variables_content[$i],$actual);
        return $actual;
    }


    /*  function to extend classes in the actual part with classes from the extended part
      * @param String - the extended part of the css
      * @param String - the actual part of the css
      * @require ($extended && $actual) != null
      * @return String - the actual part of the css file extended by the classes in the extended part
      */

    static private function extendClasses($extended,$actual) {
        preg_match_all('/([\.|#][a-zA-Z_]+)[\s]*{[\s]*([^}.]*)[\s]*}/s',$extended,$matches);
        $classes = $matches[1];
        $classes_style = $matches[2];
        for($i = 0; $i < count($classes); $i++)
           $actual = preg_replace('/extend-from: \''.$classes[$i].'\';/i',$classes_style[$i],$actual);
        $actual = preg_replace('/extended-from:[\s]*;/i','',$actual);
        return $actual;
    }
}


$file = $_GET['file'];
if(preg_match('/([a-zA-Z]+\.css)/',$file,$match)) {
    $cssparser = new CSSParser(array($file));
    $cssparser->parseFiles();
    echo file_get_contents(substr($file,0,strlen($file)-1));
}


?>

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.