initial commit
[namibia] / public / min / lib / Minify / Lines.php
1 <?php
2 /**
3  * Class Minify_Lines  
4  * @package Minify
5  */
6
7 /**
8  * Add line numbers in C-style comments for easier debugging of combined content
9  *
10  * @package Minify
11  * @author Stephen Clay <steve@mrclay.org>
12  * @author Adam Pedersen (Issue 55 fix)
13  */
14 class Minify_Lines {
15
16     /**
17      * Add line numbers in C-style comments
18      *
19      * This uses a very basic parser easily fooled by comment tokens inside
20      * strings or regexes, but, otherwise, generally clean code will not be 
21      * mangled. URI rewriting can also be performed.
22      *
23      * @param string $content
24      * 
25      * @param array $options available options:
26      * 
27      * 'id': (optional) string to identify file. E.g. file name/path
28      *
29      * 'currentDir': (default null) if given, this is assumed to be the
30      * directory of the current CSS file. Using this, minify will rewrite
31      * all relative URIs in import/url declarations to correctly point to
32      * the desired files, and prepend a comment with debugging information about
33      * this process.
34      * 
35      * @return string 
36      */
37     public static function minify($content, $options = array()) 
38     {
39         $id = (isset($options['id']) && $options['id'])
40             ? $options['id']
41             : '';
42         $content = str_replace("\r\n", "\n", $content);
43
44         // Hackily rewrite strings with XPath expressions that are
45         // likely to throw off our dumb parser (for Prototype 1.6.1).
46         $content = str_replace('"/*"', '"/"+"*"', $content);
47         $content = preg_replace('@([\'"])(\\.?//?)\\*@', '$1$2$1+$1*', $content);
48
49         $lines = explode("\n", $content);
50         $numLines = count($lines);
51         // determine left padding
52         $padTo = strlen((string) $numLines); // e.g. 103 lines = 3 digits
53         $inComment = false;
54         $i = 0;
55         $newLines = array();
56         while (null !== ($line = array_shift($lines))) {
57             if (('' !== $id) && (0 == $i % 50)) {
58                 if ($inComment) {
59                     array_push($newLines, '', "/* {$id} *|", '');
60                 } else {
61                     array_push($newLines, '', "/* {$id} */", '');
62                 }
63             }
64             ++$i;
65             $newLines[] = self::_addNote($line, $i, $inComment, $padTo);
66             $inComment = self::_eolInComment($line, $inComment);
67         }
68         $content = implode("\n", $newLines) . "\n";
69         
70         // check for desired URI rewriting
71         if (isset($options['currentDir'])) {
72             Minify_CSS_UriRewriter::$debugText = '';
73             $content = Minify_CSS_UriRewriter::rewrite(
74                  $content
75                 ,$options['currentDir']
76                 ,isset($options['docRoot']) ? $options['docRoot'] : $_SERVER['DOCUMENT_ROOT']
77                 ,isset($options['symlinks']) ? $options['symlinks'] : array()
78             );
79             $content = "/* Minify_CSS_UriRewriter::\$debugText\n\n" 
80                      . Minify_CSS_UriRewriter::$debugText . "*/\n"
81                      . $content;
82         }
83         
84         return $content;
85     }
86     
87     /**
88      * Is the parser within a C-style comment at the end of this line?
89      *
90      * @param string $line current line of code
91      * 
92      * @param bool $inComment was the parser in a comment at the
93      * beginning of the line?
94      *
95      * @return bool
96      */
97     private static function _eolInComment($line, $inComment)
98     {
99         // crude way to avoid things like // */
100         $line = preg_replace('~//.*?(\\*/|/\\*).*~', '', $line);
101
102         while (strlen($line)) {
103             $search = $inComment
104                 ? '*/'
105                 : '/*';
106             $pos = strpos($line, $search);
107             if (false === $pos) {
108                 return $inComment;
109             } else {
110                 if ($pos == 0
111                     || ($inComment
112                         ? substr($line, $pos, 3)
113                         : substr($line, $pos-1, 3)) != '*/*')
114                 {
115                         $inComment = ! $inComment;
116                 }
117                 $line = substr($line, $pos + 2);
118             }
119         }
120         return $inComment;
121     }
122     
123     /**
124      * Prepend a comment (or note) to the given line
125      *
126      * @param string $line current line of code
127      *
128      * @param string $note content of note/comment
129      * 
130      * @param bool $inComment was the parser in a comment at the
131      * beginning of the line?
132      *
133      * @param int $padTo minimum width of comment
134      * 
135      * @return string
136      */
137     private static function _addNote($line, $note, $inComment, $padTo)
138     {
139         return $inComment
140             ? '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' *| ' . $line
141             : '/* ' . str_pad($note, $padTo, ' ', STR_PAD_RIGHT) . ' */ ' . $line;
142     }
143 }