1<?php
2/**
3 * DokuWiki plugin Typography; Syntax typography base component
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Paweł Piekarski <qentinson@gmail.com>
7 * @author     Satoshi Sahara <sahara.satoshi@gmail.com>
8 */
9class syntax_plugin_typography_base extends DokuWiki_Syntax_Plugin
10{
11    public function getType()
12    {   // Syntax Type
13        return 'formatting';
14    }
15
16    public function getAllowedTypes()
17    {   // Allowed Mode Types
18        return array('formatting', 'substition', 'disabled');
19    }
20
21    /**
22     * Connect pattern to lexer
23     */
24    protected $mode, $pattern;
25
26    public function preConnect()
27    {
28        // drop 'syntax_' from class name
29        $this->mode = substr(get_class($this), 7);
30
31        // syntax pattern
32        $this->pattern[1] = '<typo\b.*?>(?=.*?</typo>)';
33        $this->pattern[4] = '</typo>';
34    }
35
36    public function connectTo($mode)
37    {
38        $this->Lexer->addEntryPattern($this->pattern[1], $mode, $this->mode);
39    }
40
41    public function postConnect()
42    {
43        $this->Lexer->addExitPattern($this->pattern[4], $this->mode);
44    }
45
46    public function getSort()
47    {   // sort number used to determine priority of this mode
48        return 67; // = Doku_Parser_Mode_formatting:strong -3
49    }
50
51    // plugin accepts its own entry syntax
52    public function accepts($mode)
53    {
54        if ($mode == $this->mode) return true;
55        return parent::accepts($mode);
56    }
57
58
59    /**
60     * Plugin features
61     */
62    protected $styler = null;
63
64
65    /*
66     * Handle the match
67     */
68    public function handle($match, $state, $pos, Doku_Handler $handler)
69    {
70        switch($state) {
71            case DOKU_LEXER_ENTER:
72                // load prameter parser utility
73                if (is_null($this->styler)) {
74                    $this->styler = $this->loadHelper('typography_parser');
75                }
76
77                // identify markup keyword of this syntax class
78                $markup = substr($this->pattern[4], 2, -1);
79
80                // get inline CSS parameter
81                $params = strtolower(ltrim(substr($match, strlen($markup)+1, -1)));
82                if ($this->styler->is_short_property($markup)) {
83                    $params = $markup.(($params[0] == ':') ? '' : ':').$params;
84                }
85
86                // get css property:value pairs as an associative array
87                $tag_data = $this->styler->parse_inlineCSS($params);
88
89                return $data = array($state, $tag_data);
90
91            case DOKU_LEXER_UNMATCHED:
92                $handler->base($match, $state, $pos);
93                return false;
94
95            case DOKU_LEXER_EXIT:
96                return $data = array($state, '');
97        }
98        return array();
99    }
100
101    /*
102     * Create output
103     */
104    public function render($format, Doku_Renderer $renderer, $data)
105    {
106        if (empty($data)) return false;
107        switch ($format) {
108            case 'xhtml':
109                return $this->render_xhtml($renderer, $data);
110            case 'odt':
111                // ODT export;
112                $odt = $this->loadHelper('typography_odt');
113                return $odt->render($renderer, $data);
114            default:
115                return false;
116        }
117    }
118
119    protected function render_xhtml(Doku_Renderer $renderer, $data)
120    {
121        list($state, $tag_data) = $data;
122        switch ($state) {
123            case DOKU_LEXER_ENTER:
124                // load prameter parser utility
125                if (is_null($this->styler)) {
126                    $this->styler = $this->loadHelper('typography_parser');
127                }
128                // build attributes (style and class)
129                $renderer->doc .= '<span'.$this->styler->build_attributes($tag_data).'>';
130                break;
131
132            case DOKU_LEXER_EXIT:
133                $renderer->doc .= '</span>';
134                break;
135        }
136        return true;
137    }
138
139}
140