* * Handles tab-delimited tables so you can cut and paste to and * from spreadsheet applications * * Developed and tested using the PmWiki 2.2.0-beta series. * * To install, add the following line to your configuration file : include_once("$FarmD/cookbook/casecorrect.php"); * and add the directive (:case-correction:) to your 404 page, by * default located at Site.PageNotFound * * For more information, please see the online documentation at * http://www.pmwiki.org/wiki/Cookbook/CaseCorrection * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License, * Version 2, as published by the Free Software Foundation. * http://www.gnu.org/copyleft/gpl.html */ $RecipeInfo['Tabulate']['Version'] = '2008-09-08'; Markup('tabulate-set', '>if', '/\\(:tab-table(.*?):\\)/ei', "TabulateSetup( \$pagename, PSS('$1') )"); Markup('tabulate-tabs', '>tabulate-set', '/^(?:.*\\t.*\n)+/me', "Tabulate( \$pagename, PSS('$0') )"); function TabulateParseArgs($x) { global $TabZeroIndexing; $z = array(); preg_match_all("/\s+(all|col|row|tgt)(\d*)[:=](\"[^\"]*\"|\\S+)/", $x, $terms, PREG_SET_ORDER); foreach( $terms as $t ) { if ( $t[2] === '' ) $t[2] = $t[3]; $z[$t[1]][$t[2]] = preg_replace('/^"(.*)"$/', '$1', $t[3] ); $x = preg_replace( '/'.preg_quote($t[0],'/').'/', '', $x ); } if ( !IsEnabled( $TabZeroIndexing, FALSE ) ) { foreach ( $z as $n => $va ) if ( is_array($va) ) foreach( $va as $p => $v ) { if ( --$p < 0 ) $p = 0; $nz[$n][$p] = $v; } else $nz[$n] = $va; $z = $nz; } $z['tail'] = trim($x); return $z; } function TabulateSetup( $pagename, $attr ) { global $TabSet; $set = TabulateParseArgs($attr); if ( isset($set['tgt']) ) { $i = key($set['tgt']); unset($set['tgt']); $TabSet[$i] = $set; } else $TabSet[] = $set; return ''; } function Tabulate( $pagename, $text ) { global $TabMinRows, $TabMinCols, $TabSet, $TabCall; SDV( $TabMinRows, 2 ); SDV( $TabMinCols, 2 ); SDV( $TabCall, 0 ); $text = trim(str_replace( array('||','\\\\'), array('||',"
"), $text )); foreach( explode("\n",$text) as $n ) $table[] = explode("\t",$n); if ( count($table) < $TabMinRows ) return $text; for ( $i = 0; $i < $TabMinRows; ++$i ) if ( count($table[$i]) < $TabMinCols ) return $text; $ts = "(:table {$TabSet[$TabCall]['tail']}:)\n"; unset($TabSet[$TabCall]['tail']); $tp = array(); foreach( (array)$TabSet[$TabCall] as $dir => $a ) if ( is_array($a) ) foreach( $a as $i => $s ) { if ( !preg_match( '/^\s*([^a-z\d]*)\s*([a-z\d%# ]*?)\s*([^a-z\d]*)\s*$/', $s, $m ) ) continue; if (!$m[3]) { if ( !$m[1] && !$m[2] ) continue; $m[3] = $m[1]; } else if (!$m[1]) $m[1] = $m[3]; if ($m[2]) { $m[2] = preg_replace( array( '/\d+(?:%|px)/i', '/#[a-f\d]{6}/i', '/\b(?:left|center|right|justify)\b/i', '/\b(?:top|middle|bottom|baseline)\b/i' ), array( 'width=$0', 'bgcolor=$0', 'align=$0', 'valign=$0' ), $m[2] ); } switch($dir) { case 'all': foreach( $table as $ri => $r ) foreach( $r as $ci => $tc ) { if ($m[1]) $table[$ri][$ci] = $m[1].$tc.$m[3]; if ($m[2]) $tp[$ri][$ci] .= ' '.$m[2]; } break; case 'row': if ( $i < count($table) ) { foreach( $table[$i] as $j => $tc ) { if ($m[1]) $table[$i][$j] = $m[1].$tc.$m[3]; if ($m[2]) $tp[$i][$j] .= ' '.$m[2]; } } break; case 'col': foreach( $table as $j => $r ) { if ( $i < count($r) ) { if ($m[1]) $table[$j][$i] = $m[1].$r[$i].$m[3]; if ($m[2]) $tp[$j][$i] .= ' '.$m[2]; } } break; } } foreach( $table as $i => $r ) foreach( $r as $j => $tc ) { $ts .= ($j?'(:cell ':'(:cellnr ') . "{$tp[$i][$j]}:)$tc\n"; } $ts .= "(:tableend:)\n"; ++$TabCall; return $ts; }