1<?php
2/**
3 * Plugin vertical : Configure vertical-align in tables.
4 *
5 * Syntax: <vertical head=bottom body=center>table</vertical>
6 *
7 * @author     Pavel Korotkiy (outdead)
8 * @license    MIT (https://opensource.org/license/mit/)
9 */
10
11if (!defined('DOKU_INC')) die();
12if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
13
14require_once(DOKU_PLUGIN.'syntax.php');
15
16class syntax_plugin_vertical extends DokuWiki_Syntax_Plugin {
17    function getInfo(){
18        return array(
19            'author' => 'outdead',
20            'email'  => 'paul.korotkiy@gmail.com',
21            'date'   => '2023-07-11',
22            'name'   => 'Table Vertical Align',
23            'desc'   => 'Simple plugin to configure vertical-align in tables',
24            'url'    => 'https://github.com/outdead/dokuwiki-plugin-vertical',
25        );
26    }
27
28    function getType() {
29        return 'container';
30    }
31
32    function getPType() {
33        return 'normal';
34    }
35
36    function getAllowedTypes() {
37        return array('container', 'substition', 'protected', 'disabled', 'formatting', 'paragraphs');
38    }
39
40    function getSort() {
41        return 137;
42    }
43
44    function connectTo($mode) {
45        $this->Lexer->addEntryPattern('<vertical[^>]*>(?=.*?</vertical>)', $mode, 'plugin_vertical');
46    }
47
48    function postConnect() {
49        $this->Lexer->addExitPattern('</vertical>', 'plugin_vertical');
50    }
51
52    function handle($match, $state, $pos, $handler){
53        switch ($state) {
54            case DOKU_LEXER_ENTER:
55                $data = strtolower(trim(substr($match, 9, -1)));
56                $data = trim($data);
57                return array($state, $data);
58            case DOKU_LEXER_UNMATCHED :
59                return array($state, $match);
60            case DOKU_LEXER_EXIT :
61                return array($state, '');
62        }
63
64        return false;
65    }
66
67    function render($mode, $renderer, $indata) {
68        if ($mode == 'xhtml') {
69            list($state, $match) = $indata;
70
71            switch ($state) {
72                case DOKU_LEXER_ENTER:
73                    $class = "";
74                    $instructions = explode(" ", htmlspecialchars($match));
75
76                    foreach ($instructions as $instruction) {
77                        $parts = explode("=", $instruction);
78
79                        if (count($parts) != 2) {
80                            continue;
81                        }
82
83                        $position = $parts[0];
84                        $align = $parts[1];
85
86                        if ($position != "head" && $position != "body") {
87                            continue;
88                        }
89
90                        if ($align != "top" && $align != "center" && $align != "bottom") {
91                            continue;
92                        }
93
94                        $class .= " vertical_${align}_${position}";
95                    }
96
97                    $class = trim($class);
98
99                    $renderer->doc .= '<div class="'.$class.'">';
100                    break;
101                case DOKU_LEXER_UNMATCHED :
102                    $renderer->doc .= $renderer->_xmlEntities($match);
103                    break;
104                case DOKU_LEXER_EXIT :
105                    $renderer->doc .= "</div>";
106                    break;
107            }
108
109            return true;
110        }
111
112        return false;
113    }
114}
115