1<?php
2/**
3 * DokuWiki StyleSheet creator
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <andi@splitbrain.org>
7 */
8
9if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../../').'/');
10if(!defined('NOSESSION')) define('NOSESSION',true); // we do not use a session or authentication here (better caching)
11if(!defined('DOKU_DISABLE_GZIP_OUTPUT')) define('DOKU_DISABLE_GZIP_OUTPUT',1); // we gzip ourself here
12if(!defined('EPUB_DIR')) define('EPUB_DIR',realpath(dirname(__FILE__).'/../').'/');
13if(!defined('DOKU_TPL')) define('DOKU_TPL', DOKU_BASE.'lib/tpl/'.$conf['template'].'/');
14if(!defined('DOKU_TPLINC')) define('DOKU_TPLINC', DOKU_INC.'lib/tpl/'.$conf['template'].'/');
15require_once(DOKU_INC.'inc/init.php');
16
17
18
19// ---------------------- functions ------------------------------
20
21/**
22 * Output all needed Styles
23 *
24 * @author Andreas Gohr <andi@splitbrain.org>
25 */
26function epub_css_out($path){
27    global $conf;
28    global $lang;
29    global $config_cascade;
30
31    $mediatype = 'screen';
32
33	$tpl = trim(preg_replace('/[^\w-]+/','',$conf['template']));
34
35    if($tpl){
36        $tplinc = DOKU_INC.'lib/tpl/'.$tpl.'/';
37        $tpldir = DOKU_BASE.'lib/tpl/'.$tpl.'/';
38    }else{
39        $tplinc = DOKU_TPLINC;
40        $tpldir = DOKU_TPL;
41    }
42
43    // load template styles
44    $tplstyles = array();
45    if(@file_exists($tplinc.'style.ini')){
46        $ini = parse_ini_file($tplinc.'style.ini',true);
47        foreach($ini['stylesheets'] as $file => $mode){
48            $tplstyles[$mode][$tplinc.$file] = $tpldir;
49        }
50    }
51
52    // Array of needed files and their web locations, the latter ones
53    // are needed to fix relative paths in the stylesheets
54    $files   = array();
55
56      $files[DOKU_INC.'lib/styles/style.css'] = DOKU_BASE.'lib/styles/';
57        // load plugin, template, user styles
58        $files = array_merge($files, css_pluginstyles('screen'));
59        $files = array_merge($files, css_pluginstyles('all'));
60        if (isset($tplstyles['screen'])) $files = array_merge($files, $tplstyles['screen']);
61        if($lang['direction'] == 'rtl'){
62            if (isset($tplstyles['rtl'])) $files = array_merge($files, $tplstyles['rtl']);
63        }
64        if(isset($config_cascade['userstyle']['default'])){
65            $files[$config_cascade['userstyle']['default']] = DOKU_BASE;
66        }
67     if (isset($tplstyles[$mediatype])) {
68        $files = array_merge($files, $tplstyles[$mediatype]);
69     }
70
71    // load user styles
72    if(isset($config_cascade['userstyle'][$mediatype])){
73        $files[$config_cascade['userstyle'][$mediatype]] = DOKU_BASE;
74    }
75
76    // load files
77    $css = "";
78    foreach($files as $file => $location){
79        $css .= css_loadfile($file, $location);
80    }
81
82    // apply style replacements
83    $css = css_applystyle($css,$tplinc);
84
85    // place all @import statements at the top of the file
86    $css = css_moveimports($css);
87    io_saveFile($path . 'Styles/style.css' ,$css);
88
89}
90
91
92
93/**
94 * Does placeholder replacements in the style according to
95 * the ones defined in a templates style.ini file
96 *
97 * @author Andreas Gohr <andi@splitbrain.org>
98 */
99function css_applystyle($css,$tplinc){
100    if(@file_exists($tplinc.'style.ini')){
101        $ini = parse_ini_file($tplinc.'style.ini',true);
102        $css = strtr($css,$ini['replacements']);
103    }
104    return $css;
105}
106
107
108/**
109 * Prints classes for file download links
110 *
111 * @author Andreas Gohr <andi@splitbrain.org>
112 */
113
114/**
115 * Loads a given file and fixes relative URLs with the
116 * given location prefix
117 */
118function css_loadfile($file,$location=''){
119    if(!@file_exists($file)) return '';
120    $css = io_readFile($file);
121    if(!$location) return $css;
122
123    $css = preg_replace('#(url\([ \'"]*)(?!/|http://|https://| |\'|")#','\\1'.$location,$css);
124    $css = preg_replace('#(@import\s+[\'"])(?!/|http://|https://)#', '\\1'.$location, $css);
125    return $css;
126}
127
128
129/**
130 * Move all @import statements in a combined stylesheet to the top so they
131 * aren't ignored by the browser.
132 *
133 * @author Gabriel Birke <birke@d-scribe.de>
134 */
135function css_moveimports($css)
136{
137    if(!preg_match_all('/@import\s+(?:url\([^)]+\)|"[^"]+")\s*[^;]*;\s*/', $css, $matches, PREG_OFFSET_CAPTURE)) {
138        return $css;
139    }
140    $newCss  = "";
141    $imports = "";
142    $offset  = 0;
143    foreach($matches[0] as $match) {
144        $newCss  .= substr($css, $offset, $match[1] - $offset);
145        $imports .= $match[0];
146        $offset   = $match[1] + strlen($match[0]);
147    }
148    $newCss .= substr($css, $offset);
149    return $imports.$newCss;
150}
151
152function css_pluginstyles($mode='screen'){
153    global $lang;
154    $list = array();
155    $plugins = plugin_list();
156    foreach ($plugins as $p){
157        if($mode == 'all'){
158            $list[DOKU_PLUGIN."$p/all.css"]  = DOKU_BASE."lib/plugins/$p/";
159        }elseif($mode == 'print'){
160            $list[DOKU_PLUGIN."$p/print.css"]  = DOKU_BASE."lib/plugins/$p/";
161        }elseif($mode == 'feed'){
162            $list[DOKU_PLUGIN."$p/feed.css"]  = DOKU_BASE."lib/plugins/$p/";
163        }else{
164            $list[DOKU_PLUGIN."$p/style.css"]  = DOKU_BASE."lib/plugins/$p/";
165            $list[DOKU_PLUGIN."$p/screen.css"] = DOKU_BASE."lib/plugins/$p/";
166        }
167        if($lang['direction'] == 'rtl'){
168            $list[DOKU_PLUGIN."$p/rtl.css"] = DOKU_BASE."lib/plugins/$p/";
169        }
170    }
171    return $list;
172}
173
174//echo epub_css_out(EPUB_DIR);
175//Setup VIM: ex: et ts=4 :
176