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 $tableAlign = preg_match('/[<>]+/', $width[0]) == 1 ? array_shift($width) : '-'; 50 $tableWidth = array_shift($width); 51 52 if ($tableWidth != '-' || $tableAlign != '-') { 53 $table = $this->styleTable($data[2][0], $tableWidth, $tableAlign); 54 } 55 else { 56 $table = $data[2][0]; 57 } 58 59 return $table . $this->renderColumns($width) . $data[3][0]; 60 } 61 62 /** 63 * Add width and align styles to the table 64 */ 65 private function styleTable($html, $width, $align) { 66 preg_match('/^([^\n]*<table)(.*?)(>)$/', $html, $match); 67 68 $entry = $match[1]; 69 $attributes = $match[2]; 70 $exit = $match[3]; 71 72 $widthStyle = $this->getTableWidthStyle($width); 73 $alignStyle = $this->getTableAlignStyle($align); 74 $tableStyle = implode(' ', array_filter([$widthStyle, $alignStyle])); 75 76 if (preg_match('/(.*?style\s*=\s*(["\']).*?)(\2.*)/', $attributes, $match) == 1) { 77 $attributes = $match[1] . '; ' . $tableStyle . $match[3]; 78 } 79 else { 80 $attributes .= ' style="' . $tableStyle . '"'; 81 } 82 83 return $entry . $attributes . $exit; 84 } 85 86 /** 87 * Return table width style 88 */ 89 private function getTableWidthStyle($width) { 90 if ($width != '-') { 91 return 'min-width: 0; width: ' . $width . ';'; 92 } 93 94 return ''; 95 } 96 97 /** 98 * Return table align style 99 */ 100 private function getTableAlignStyle($align) { 101 switch ($align) { 102 case '><': 103 return 'margin-left: auto; margin-right: auto;'; 104 case '>': 105 return 'margin-left: auto; margin-right: 0;'; 106 case '<': 107 return 'margin-left: 0; margin-right: auto;'; 108 } 109 110 return ''; 111 } 112 113 /** 114 * Render column tags 115 */ 116 private function renderColumns($width) { 117 $html = DOKU_LF; 118 119 foreach ($width as $w) { 120 if ($w != '-') { 121 $html .= '<col style="width: ' . $w . '" />'; 122 } 123 else { 124 $html .= '<col />'; 125 } 126 } 127 128 return $html; 129 } 130} 131