1<?php
2/**
3 * overrides for DokuWiki StyleSheet creator
4 */
5if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
6if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
7if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
8require_once(DOKU_INC.'inc/init.php');
9require_once(DOKU_INC.'inc/pageutils.php');
10require_once(DOKU_INC.'inc/httputils.php');
11require_once(DOKU_INC.'inc/io.php');
12require_once(DOKU_INC.'inc/confutils.php');
13
14// Main (don't run when UNIT test)
15if(!defined('SIMPLE_TEST')){
16    header('Content-Type: text/css; charset=utf-8');
17    _css_out();
18}
19
20
21// ---------------------- functions ------------------------------
22
23/**
24 * Output all needed Styles
25 *
26 * @author Andreas Gohr <andi@splitbrain.org>
27 */
28function _css_out(){
29    global $conf;
30    global $lang;
31    global $config_cascade;
32    global $INPUT;
33
34    if ($INPUT->str('s') == 'feed') {
35        $mediatypes = array('feed');
36        $type = 'feed';
37    } else {
38        $mediatypes = array('screen', 'all', 'print');
39        $type = '';
40    }
41
42    $tpl = trim(preg_replace('/[^\w-]+/','',$INPUT->str('t')));
43    if($tpl){
44        #$tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
45        $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
46    }else{
47        #$tplinc = tpl_incdir();
48        $tpldir = tpl_basedir();
49    }
50
51    foreach( array( 'style.ini', 'style.local.ini' ) as $ini ) {
52        $ini = _css_getpath( $tpl, $ini );
53        if( @file_exists( $ini )) {
54            $tplinc[] = $ini;
55        }
56    }
57
58    // used style.ini file
59    $styleini = _css_styleini($tplinc);
60
61    // The generated script depends on some dynamic options
62    $cache = new cache('styles'.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'].DOKU_BASE.$cache.$mediatype,'.css');
63
64    // load template styles
65    $tplstyles = array();
66    if ($styleini) {
67        foreach($styleini['stylesheets'] as $file => $mode) {
68            $tplstyles[$mode][_css_getpath( $tpl, $file )] = $tpldir;
69        }
70    }
71
72    // if old 'default' userstyle setting exists, make it 'screen' userstyle for backwards compatibility
73    if (isset($config_cascade['userstyle']['default'])) {
74        $config_cascade['userstyle']['screen'] = $config_cascade['userstyle']['default'];
75    }
76
77    // Array of needed files and their web locations, the latter ones
78    // are needed to fix relative paths in the stylesheets
79    $files = array();
80
81    $cache_files = getConfigFiles('main');
82    foreach( $tplinc as $ini ) {
83	    $cache_files[] = $ini;
84    }
85    $cache_files[] = __FILE__;
86
87    foreach($mediatypes as $mediatype) {
88        $files[$mediatype] = array();
89        // load core styles
90        $files[$mediatype][DOKU_INC.'lib/styles/'.$mediatype.'.css'] = DOKU_BASE.'lib/styles/';
91        // load jQuery-UI theme
92        if ($mediatype == 'screen') {
93            $files[$mediatype][DOKU_INC.'lib/scripts/jquery/jquery-ui-theme/smoothness.css'] = DOKU_BASE.'lib/scripts/jquery/jquery-ui-theme/';
94        }
95        // load plugin styles
96        $files[$mediatype] = array_merge($files[$mediatype], css_pluginstyles($mediatype));
97        // load template styles
98        if (isset($tplstyles[$mediatype])) {
99            $files[$mediatype] = array_merge($files[$mediatype], $tplstyles[$mediatype]);
100        }
101        // load user styles
102        if(isset($config_cascade['userstyle'][$mediatype])){
103            $files[$mediatype][$config_cascade['userstyle'][$mediatype]] = DOKU_BASE;
104        }
105        // load rtl styles
106        // note: this adds the rtl styles only to the 'screen' media type
107        // @deprecated 2012-04-09: rtl will cease to be a mode of its own,
108        //     please use "[dir=rtl]" in any css file in all, screen or print mode instead
109        if ($mediatype=='screen') {
110            if($lang['direction'] == 'rtl'){
111                if (isset($tplstyles['rtl'])) $files[$mediatype] = array_merge($files[$mediatype], $tplstyles['rtl']);
112                if (isset($config_cascade['userstyle']['rtl'])) $files[$mediatype][$config_cascade['userstyle']['rtl']] = DOKU_BASE;
113            }
114        }
115
116        $cache_files = array_merge($cache_files, array_keys($files[$mediatype]));
117    }
118
119    // check cache age & handle conditional request
120    // This may exit if a cache can be used
121    http_cached($cache->cache,
122                $cache->useCache(array('files' => $cache_files)));
123
124    // start output buffering
125    ob_start();
126
127    // build the stylesheet
128    foreach ($mediatypes as $mediatype) {
129
130        // print the default classes for interwiki links and file downloads
131        if ($mediatype == 'screen') {
132            print '@media screen {';
133            css_interwiki();
134            css_filetypes();
135            print '}';
136        }
137
138        // load files
139        $css_content = '';
140        foreach($files[$mediatype] as $file => $location){
141            $css_content .= css_loadfile($file, $location);
142        }
143        switch ($mediatype) {
144            case 'screen':
145                print NL.'@media screen { /* START screen styles */'.NL.$css_content.NL.'} /* /@media END screen styles */'.NL;
146                break;
147            case 'print':
148                print NL.'@media print { /* START print styles */'.NL.$css_content.NL.'} /* /@media END print styles */'.NL;
149                break;
150            case 'all':
151            case 'feed':
152            default:
153                print NL.'/* START rest styles */ '.NL.$css_content.NL.'/* END rest styles */'.NL;
154                break;
155        }
156    }
157    // end output buffering and get contents
158    $css = ob_get_contents();
159    ob_end_clean();
160
161    // apply style replacements
162    $css = _css_applystyle($css,$tplinc);
163
164    // place all @import statements at the top of the file
165    $css = css_moveimports($css);
166
167    // compress whitespace and comments
168    if($conf['compress']){
169        $css = css_compress($css);
170    }
171
172    // embed small images right into the stylesheet
173    if($conf['cssdatauri']){
174        $base = preg_quote(DOKU_BASE,'#');
175        $css = preg_replace_callback('#(url\([ \'"]*)('.$base.')(.*?(?:\.(png|gif)))#i','css_datauri',$css);
176    }
177
178    http_cached_finish($cache->cache, $css);
179}
180
181function _css_applystyle($css,$tplinc){
182    $styleini = _css_styleini($tplinc);
183
184    if($styleini){
185        $css = strtr($css,$styleini['replacements']);
186    }
187    return $css;
188}
189function _css_styleini($tplinc) {
190    $styleini = array();
191
192    foreach( $tplinc as $ini) {
193        $tmp = (@file_exists($ini)) ? parse_ini_file($ini, true) : array();
194
195        foreach($tmp as $key => $value) {
196            if(array_key_exists($key, $styleini) && is_array($value)) {
197                $styleini[$key] = array_merge($styleini[$key], $tmp[$key]);
198            } else {
199                $styleini[$key] = $value;
200            }
201        }
202    }
203    return $styleini;
204}
205function _css_getpath( $t, $file ) {
206    global $conf;
207
208    if( !$t ) { $t = $conf['template']; }
209    if( !$t || !$include = getConfigPath( 'template_dir', $t.'/'.$file )) {
210
211        if( $conf['template'] && $t != $conf['template'] )
212            $include = getConfigPath( 'template_dir', $conf['template'].'/'.$file );
213        elseif( $conf['default_tpl'] && $t != $conf['default_tpl'] )
214            $include = getConfigPath( 'template_dir', $conf['default_tpl'].'/'.$file );
215    }
216    if( !$include ) {
217        $include = getConfigPath( 'template_dir', $conf['base_tpl'].'/'.$file );
218    }
219    echo "/* _css_getpath: include($file): $include */\n";
220
221    return $include;
222}
223
224//Setup VIM: ex: et ts=4 :
225