xref: /plugin/tablewidth/action.php (revision 238f584e2c768f65a57ff710428becbae2a13ae7)
1a30194adSMykola Ostrovskyy<?php
2a30194adSMykola Ostrovskyy
3a30194adSMykola Ostrovskyy/**
4a30194adSMykola Ostrovskyy * Plugin TableWidth
5a30194adSMykola Ostrovskyy *
6a30194adSMykola Ostrovskyy * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7b5ba902fSMykola Ostrovskyy * @author     Mykola Ostrovskyy <dwpforge@gmail.com>
8a30194adSMykola Ostrovskyy */
9a30194adSMykola Ostrovskyy
10d0a907abSMykola Ostrovskyyclass action_plugin_tablewidth extends DokuWiki_Action_Plugin {
11a30194adSMykola Ostrovskyy
12a30194adSMykola Ostrovskyy    /**
13a30194adSMykola Ostrovskyy     * Register callbacks
14a30194adSMykola Ostrovskyy     */
157ef3101aSMykola Ostrovskyy    public function register(Doku_Event_Handler $controller) {
16a30194adSMykola Ostrovskyy        $controller->register_hook('RENDERER_CONTENT_POSTPROCESS', 'AFTER', $this, 'replaceComments');
17a30194adSMykola Ostrovskyy    }
18a30194adSMykola Ostrovskyy
19a30194adSMykola Ostrovskyy    /**
20d0a907abSMykola Ostrovskyy     * Replace table-width comments by HTML
21a30194adSMykola Ostrovskyy     */
227ef3101aSMykola Ostrovskyy    public function replaceComments(&$event, $param) {
23a30194adSMykola Ostrovskyy        if ($event->data[0] == 'xhtml') {
24716fc9d4SMykola Ostrovskyy            $pattern = '/(<!-- table-width [^\n]+? -->\n)([^\n]*<table.*?>)(\s*<t)/';
25a30194adSMykola Ostrovskyy            $flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;
267ef3101aSMykola Ostrovskyy
27d0a907abSMykola Ostrovskyy            if (preg_match_all($pattern, $event->data[1], $match, $flags) > 0) {
28d0a907abSMykola Ostrovskyy                $start = 0;
29d0a907abSMykola Ostrovskyy                $html = '';
307ef3101aSMykola Ostrovskyy
31d0a907abSMykola Ostrovskyy                foreach ($match as $data) {
32d0a907abSMykola Ostrovskyy                    $html .= substr($event->data[1], $start, $data[0][1] - $start);
337ef3101aSMykola Ostrovskyy                    $html .= $this->processTable($data);
34d0a907abSMykola Ostrovskyy                    $start = $data[0][1] + strlen($data[0][0]);
35d0a907abSMykola Ostrovskyy                }
367ef3101aSMykola Ostrovskyy
37156ac918SMykola Ostrovskyy                $event->data[1] = $html . substr($event->data[1], $start);
38a30194adSMykola Ostrovskyy            }
39a30194adSMykola Ostrovskyy        }
40a30194adSMykola Ostrovskyy    }
41d0a907abSMykola Ostrovskyy
42d0a907abSMykola Ostrovskyy    /**
43d0a907abSMykola Ostrovskyy     * Convert table-width comments and table mark-up into final HTML
44d0a907abSMykola Ostrovskyy     */
457ef3101aSMykola Ostrovskyy    private function processTable($data) {
46d0a907abSMykola Ostrovskyy        preg_match('/<!-- table-width ([^\n]+?) -->/', $data[1][0], $match);
477ef3101aSMykola Ostrovskyy
48d0a907abSMykola Ostrovskyy        $width = preg_split('/\s+/', $match[1]);
49ea642877SMykola Ostrovskyy        $tableAlign = preg_match('/[<>]+/', $width[0]) == 1 ? array_shift($width) : '-';
50d0a907abSMykola Ostrovskyy        $tableWidth = array_shift($width);
517ef3101aSMykola Ostrovskyy
52ea642877SMykola Ostrovskyy        if ($tableWidth != '-' || $tableAlign != '-') {
53ea642877SMykola Ostrovskyy            $table = $this->styleTable($data[2][0], $tableWidth, $tableAlign);
54d0a907abSMykola Ostrovskyy        }
55d0a907abSMykola Ostrovskyy        else {
56d0a907abSMykola Ostrovskyy            $table = $data[2][0];
57d0a907abSMykola Ostrovskyy        }
587ef3101aSMykola Ostrovskyy
597ef3101aSMykola Ostrovskyy        return $table . $this->renderColumns($width) . $data[3][0];
60d0a907abSMykola Ostrovskyy    }
61d0a907abSMykola Ostrovskyy
62d0a907abSMykola Ostrovskyy    /**
63ea642877SMykola Ostrovskyy     * Add width and align styles to the table
64d0a907abSMykola Ostrovskyy     */
65ea642877SMykola Ostrovskyy    private function styleTable($html, $width, $align) {
66716fc9d4SMykola Ostrovskyy        preg_match('/^([^\n]*<table)(.*?)(>)$/', $html, $match);
677ef3101aSMykola Ostrovskyy
68d0a907abSMykola Ostrovskyy        $entry = $match[1];
69d0a907abSMykola Ostrovskyy        $attributes = $match[2];
70d0a907abSMykola Ostrovskyy        $exit = $match[3];
71ea642877SMykola Ostrovskyy
72ea642877SMykola Ostrovskyy        $widthStyle = $this->getTableWidthStyle($width);
73ea642877SMykola Ostrovskyy        $alignStyle = $this->getTableAlignStyle($align);
74ea642877SMykola Ostrovskyy        $tableStyle = implode(' ', array_filter([$widthStyle, $alignStyle]));
757ef3101aSMykola Ostrovskyy
76d0a907abSMykola Ostrovskyy        if (preg_match('/(.*?style\s*=\s*(["\']).*?)(\2.*)/', $attributes, $match) == 1) {
77ea642877SMykola Ostrovskyy            $attributes = $match[1] . '; ' . $tableStyle . $match[3];
78d0a907abSMykola Ostrovskyy        }
79d0a907abSMykola Ostrovskyy        else {
80ea642877SMykola Ostrovskyy            $attributes .= ' style="' . $tableStyle . '"';
81d0a907abSMykola Ostrovskyy        }
827ef3101aSMykola Ostrovskyy
83d0a907abSMykola Ostrovskyy        return $entry . $attributes . $exit;
84d0a907abSMykola Ostrovskyy    }
85d0a907abSMykola Ostrovskyy
86d0a907abSMykola Ostrovskyy    /**
87ea642877SMykola Ostrovskyy     * Return table width style
88ea642877SMykola Ostrovskyy     */
89ea642877SMykola Ostrovskyy    private function getTableWidthStyle($width) {
90ea642877SMykola Ostrovskyy        if ($width != '-') {
91ea642877SMykola Ostrovskyy            return 'min-width: 0; width: ' . $width . ';';
92ea642877SMykola Ostrovskyy        }
93ea642877SMykola Ostrovskyy
94ea642877SMykola Ostrovskyy        return '';
95ea642877SMykola Ostrovskyy    }
96ea642877SMykola Ostrovskyy
97ea642877SMykola Ostrovskyy    /**
98ea642877SMykola Ostrovskyy     * Return table align style
99ea642877SMykola Ostrovskyy     */
100ea642877SMykola Ostrovskyy    private function getTableAlignStyle($align) {
101ea642877SMykola Ostrovskyy        switch ($align) {
102ea642877SMykola Ostrovskyy            case '><':
103ea642877SMykola Ostrovskyy                return 'margin-left: auto; margin-right: auto;';
104ea642877SMykola Ostrovskyy            case '>':
105ea642877SMykola Ostrovskyy                return 'margin-left: auto; margin-right: 0;';
106ea642877SMykola Ostrovskyy            case '<':
107ea642877SMykola Ostrovskyy                return 'margin-left: 0; margin-right: auto;';
108ea642877SMykola Ostrovskyy        }
109ea642877SMykola Ostrovskyy
110ea642877SMykola Ostrovskyy        return '';
111ea642877SMykola Ostrovskyy    }
112ea642877SMykola Ostrovskyy
113ea642877SMykola Ostrovskyy    /**
114d0a907abSMykola Ostrovskyy     * Render column tags
115d0a907abSMykola Ostrovskyy     */
1167ef3101aSMykola Ostrovskyy    private function renderColumns($width) {
117d0a907abSMykola Ostrovskyy        $html = DOKU_LF;
1187ef3101aSMykola Ostrovskyy
119*238f584eSfiwswe        if (!empty($width)) {
120*238f584eSfiwswe            $html .= '<colgroup>';
121d0a907abSMykola Ostrovskyy            foreach ($width as $w) {
122d0a907abSMykola Ostrovskyy                if ($w != '-') {
123d0a907abSMykola Ostrovskyy                    $html .= '<col style="width: ' . $w . '" />';
124d0a907abSMykola Ostrovskyy                }
125d0a907abSMykola Ostrovskyy                else {
126d0a907abSMykola Ostrovskyy                    $html .= '<col />';
127d0a907abSMykola Ostrovskyy                }
128d0a907abSMykola Ostrovskyy            }
129*238f584eSfiwswe            $html .= '</colgroup>';
130*238f584eSfiwswe        }
1317ef3101aSMykola Ostrovskyy
132d0a907abSMykola Ostrovskyy        return $html;
133d0a907abSMykola Ostrovskyy    }
134a30194adSMykola Ostrovskyy}
135