1<?php
2
3/**
4 * Plugin TableWidth
5 *
6 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author     Mykola Ostrovskyy <dwpforge@gmail.com>
8 */
9
10class action_plugin_tablewidth extends DokuWiki_Action_Plugin {
11
12    /**
13     * Register callbacks
14     */
15    public function register(Doku_Event_Handler $controller) {
16        $controller->register_hook('RENDERER_CONTENT_POSTPROCESS', 'AFTER', $this, 'replaceComments');
17    }
18
19    /**
20     * Replace table-width comments by HTML
21     */
22    public function replaceComments(&$event, $param) {
23        if ($event->data[0] == 'xhtml') {
24            $pattern = '/(<!-- table-width [^\n]+? -->\n)([^\n]*<table.*?>)(\s*<t)/';
25            $flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;
26
27            if (preg_match_all($pattern, $event->data[1], $match, $flags) > 0) {
28                $start = 0;
29                $html = '';
30
31                foreach ($match as $data) {
32                    $html .= substr($event->data[1], $start, $data[0][1] - $start);
33                    $html .= $this->processTable($data);
34                    $start = $data[0][1] + strlen($data[0][0]);
35                }
36
37                $event->data[1] = $html . substr($event->data[1], $start);;
38            }
39        }
40    }
41
42    /**
43     * Convert table-width comments and table mark-up into final HTML
44     */
45    private function processTable($data) {
46        preg_match('/<!-- table-width ([^\n]+?) -->/', $data[1][0], $match);
47
48        $width = preg_split('/\s+/', $match[1]);
49        $tableWidth = array_shift($width);
50
51        if ($tableWidth != '-') {
52            $table = $this->styleTable($data[2][0], $tableWidth);
53        }
54        else {
55            $table = $data[2][0];
56        }
57
58        return $table . $this->renderColumns($width) . $data[3][0];
59    }
60
61    /**
62     * Add width style to the table
63     */
64    private function styleTable($html, $width) {
65        preg_match('/^([^\n]*<table)(.*?)(>)$/', $html, $match);
66
67        $entry = $match[1];
68        $attributes = $match[2];
69        $exit = $match[3];
70        $widthStyle = 'min-width: 0px; width: ' . $width . ';';
71
72        if (preg_match('/(.*?style\s*=\s*(["\']).*?)(\2.*)/', $attributes, $match) == 1) {
73            $attributes = $match[1] . '; ' . $widthStyle . $match[3];
74        }
75        else {
76            $attributes .= ' style="' . $widthStyle . '"';
77        }
78
79        return $entry . $attributes . $exit;
80    }
81
82    /**
83     * Render column tags
84     */
85    private function renderColumns($width) {
86        $html = DOKU_LF;
87
88        foreach ($width as $w) {
89            if ($w != '-') {
90                $html .= '<col style="width: ' . $w . '" />';
91            }
92            else {
93                $html .= '<col />';
94            }
95        }
96
97        return $html;
98    }
99}
100