1<?php
2/**
3 *  Indexmenu2 plugin, Navigation component
4 *
5 *  $Id: shortcut.php 43 2007-02-04 17:01:50Z wingedfox $
6 *  $HeadURL: https://svn.debugger.ru/repos/common/DokuWiki/Shortcut/tags/Shortcut.v0.1.0/syntax/shortcut.php $
7 *
8 *  Syntax:     <shortcut name|image> Description for the footnote </navigation>
9 *
10 *  @lastmodified $Date: 2007-02-04 20:01:50 +0300 (Вск, 04 Фев 2007) $
11 *  @license      LGPL 2 (http://www.gnu.org/licenses/lgpl.html)
12 *  @author       Ilya Lebedev <ilya@lebedev.net>
13 *  @version      $Rev: 43 $
14 *  @copyright    (c) 2005-2007, Ilya Lebedev
15 */
16
17if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
18if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
19require_once(DOKU_PLUGIN.'syntax.php');
20
21/**
22 * All DokuWiki plugins to extend the parser/rendering mechanism
23 * need to inherit from this class
24 */
25class syntax_plugin_shortcut_shortcut extends DokuWiki_Syntax_Plugin {
26
27    var $syntax = "";
28
29    /**
30     * return some info
31     */
32    function getInfo(){
33        preg_match("#^.*?Shortcut/([^\\/]+)#"," $HeadURL: https://svn.debugger.ru/repos/common/DokuWiki/Shortcut/tags/Shortcut.v0.1.0/syntax/shortcut.php $ ", $v);
34        $v = preg_replace("#.*?((trunk|.v)[\d.]+)#","\\1",$v[1]);
35        $b = preg_replace("/\\D/","", " $Rev: 43 $ ");
36
37        return array( 'author' => 'Ilya Lebedev'
38                     ,'email'  => 'ilya@lebedev.net'
39                     ,'date'   => preg_replace("#.*?(\d{4}-\d{2}-\d{2}).*#","\\1",'$Date: 2007-02-04 20:01:50 +0300 (Вск, 04 Фев 2007) $')
40                     ,'name'   => "Shortcut definition module {$v}.$b"
41                     ,'desc'   => 'Module is used to define the shortcut to the current page'
42                     ,'url'    => 'http://wiki.splitbrain.org/plugin:shortcut'
43                    );
44    }
45
46    function getType(){ return 'protected';}
47    function getPType(){ return 'block'; }
48
49    // must return a number lower than returned by native 'anchor' mode (210)
50    function getSort(){ return 123; }
51
52
53    /**
54     * Connect pattern to lexer
55     */
56    function connectTo($mode) {
57        $this->Lexer->addEntryPattern("<shortcut(?=[^\r\n]*?\x3E.*?\x3C/shortcut\x3E)",$mode,'plugin_shortcut_shortcut');
58    }
59
60    function postConnect() {
61        $this->Lexer->addExitPattern('\x3C/shortcut\x3E', 'plugin_shortcut_shortcut');
62    }
63
64    /**
65     * Handle the match
66     */
67    function handle($match, $state, $pos, &$handler){
68
69        switch ($state) {
70            case DOKU_LEXER_ENTER:
71                $this->syntax = substr($match, 1);
72                return false;
73
74            case DOKU_LEXER_UNMATCHED:
75                // will include everything from <shortcut ... to ... </shortcut>
76                // e.g. ... [name][|image]> [description]
77                list($opts, $content) = preg_split('/>/u',trim($match),2);
78
79                return array(true, $content, $opts);
80        }
81        return false;
82    }
83
84    /**
85     * Create output
86     */
87    function render($mode, &$renderer, $data) {
88        switch ($mode) {
89            case 'xhtml' :
90                if (true === $data[0]) {
91                    list(, $desc, $opts) = $data;
92                    $opts = explode('|', $opts);
93                    $opts[0] = cleanID($opts[0]);
94                    $opts[1] = trim($opts[1]);
95
96
97                    $id = getID();
98                    $meta = p_get_metadata('shortcuts');
99                    $m_s = $meta['shortcut'];
100                    if (!is_array($m_s)) $m_s = array();
101                    if (!$m_s[$opts[0]] || $m_s[$opts[0]]['target'] != $id) {
102                        $instr = p_get_instructions("(($desc))");
103                        $this->__cleanInstructions($instr);
104                        /*
105                        *  add metadata, if shortcut is not registered yet
106                        *  or target differs from the current page
107                        */
108                        $m_s[$opts[0]] = array ( 'title' => p_get_first_heading($id)
109                                                ,'target'=> $id
110                                                ,'img'   => $opts[1]
111                                                ,'desc'  => $instr
112                                               );
113                        if ($opts[1]) {
114                                /*
115                                *  update CSS
116                                */
117                                $f = @file_get_contents(DOKU_PLUGIN."/shortcut/style.css");
118                                $c_id = 'shortcut_'.str_replace(":","_",cleanID($id));//preg_replace("/[^a-z0-9_]/","",$id);
119                                $img = getimagesize(mediaFN('shortcuts:'.$opts[1]));
120                                /*
121                                *  replace structure
122                                *  [css_comment_open] shortcut_id [css_comment_close]
123                                *  [style_definition]
124                                *  [css_comment_open] @ [css_comment_close]
125                                */
126                                $f = preg_replace("#/\\*\\s*".$c_id."[^@]+@\\s*\\*/\s*#sm","",$f);
127                                $f .=   "/* $c_id */\n" .
128                                                "a#$c_id {" .
129                                                        "background: transparent url(\"".ml('shortcuts:'.$opts[1])."\") no-repeat center left; " .
130                                                        "display: inline-block; " .
131                                                        "height: ". $img[1] . "px;" .
132                                                        "line-height: ". $img[1] . "px;" .
133                                                        "margin-left: 2px;" .
134                                                        "padding-left: ". ($img[0]+2) . "px;" .
135                                                "}\n" .
136                                                "a#$c_id span { display :none }\n".
137                                                "/* @ */\n";
138                                io_saveFile(DOKU_PLUGIN."/shortcut/style.css",$f,false);
139                        }
140                        $meta['shortcut'] = $m_s;
141                        p_set_metadata('shortcuts', $meta, false, false);
142                    }
143//                    $renderer->doc .= syntax_plugin_indexmenu_indexmenu::getHTML ($opts[1], $instr);
144
145                    return true;
146                }
147                break;
148            default:
149                break;
150        }
151        return false;
152    }
153    /**
154     *  Clean instructions from unallowed stuff
155     *
156     *  @author Ilya Lebedev <ilya@lebedev.net>
157     *  @param $instr mixed list of instructions
158     *  @return mixed filtered list
159     *  @access private
160     */
161    function __cleanInstructions (&$instr) {
162        foreach ($instr as $k=>$v) {
163            switch ($v[0]) {
164                case "document_start":
165                case "document_end":
166                case "p_open":
167                case "p_close":
168                    unset($instr[$k]);
169            }
170        }
171    }
172}
173
174//Setup VIM: ex: et ts=4 enc=utf-8 :
175