1<?php 2/** 3 * Plugin Linebreak: Inserts a line break 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Christopher Smith <chris@jalakai.co.uk> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13require_once(DOKU_PLUGIN.'action.php'); 14 15/** 16 * All DokuWiki plugins to extend the parser/rendering mechanism 17 * need to inherit from this class 18 */ 19class action_plugin_linebreak extends DokuWiki_Action_Plugin { 20 21 var $marker_id = 0; 22 var $linebreak_conversions = array(); 23 24 /** 25 * return some info 26 */ 27 function getInfo(){ 28 return array( 29 'author' => 'Christopher Smith', 30 'email' => 'chris@jalakai.co.uk', 31 'date' => '2007-02-18', 32 'name' => 'Linebreak Plugin', 33 'desc' => 'Provide a line break for a new line in the raw wiki data', 34 'url' => 'http://wiki.splitbrain.org/plugin:linebreak', 35 ); 36 } 37 38 /** 39 * plugin should use this method to register its handlers with the dokuwiki's event controller 40 */ 41 function register(&$controller) { 42 $controller->register_hook('PARSER_WIKITEXT_PREPROCESS', 'BEFORE', $this, '_addspaces', NULL); 43 $controller->register_hook('PARSER_HANDLER_DONE','BEFORE', $this, '_fixsecedit', NULL); 44 } 45 46 /** 47 * add spaces before line breaks, required so syntax component pattern will match correctly 48 * record the offset changes so we can fix up the section edit offsets later 49 */ 50 function _addspaces(&$event, $param) { 51 52 // preg pattern used to find line breaks which require spaces inserted before them 53 $pattern = '/(?!< )(\n+|$)/'; 54 55 // marker to add at the start of the raw wiki data, it contains an id we use to access the location 56 // of the additional spaces added into the file 57 $marker = "~~LINEBREAK#{$this->marker_id}~~\n"; 58 59 // get the location (offset) of all the spaces to be added 60 $linebreaks = array(); 61 preg_match_all($pattern, $event->data, $linebreaks, PREG_OFFSET_CAPTURE); 62 63 for ($i=0; $i<count($linebreaks[0]); $i++) { 64 $conversion[] = $linebreaks[0][$i][1]; 65 } 66 67 // save details of the added spaces 68 $this->linebreak_conversions[$this->marker_id] = $conversion; 69 70 // add in the spaces 71 $event->data = $marker.preg_replace($pattern,' $1',$event->data); 72 73 // update the marker id so that the next use gets a fresh id. 74 $this->marker_id++; 75 } 76 77 function _fixsecedit(&$event, $param) { 78 79 // find our linebreak marker instruction and get the marker id 80 $calls =& $event->data->calls; 81 $marker = null; 82 83 for ($i=0; $i < count($calls); $i++) { 84 if ($calls[$i][0] == 'plugin' && $calls[$i][1][0] == 'linebreak' && isset($calls[$i][1][1]['marker'])) { 85 $marker = $calls[$i][1][1]['marker']; 86 break; 87 } 88 } 89 90 if (is_null($marker)) return; 91 92 // calculate the amount added to the start of the raw wiki data for our marker tag 93 $this->base_delta = strlen("~~LINEBREAK#$marker~~\n"); 94 $this->current_marker = $marker; 95 96 // iterate through the instruction list and set the file offset values (usually the $pos variable) 97 // back to the values they would be if no spaces had been added by this plugin 98 for ($i=0; $i < count($calls); $i++) { 99 if ($calls[$i][0] == 'section_edit') { 100 $calls[$i][1][0] = $this->_convert($calls[$i][1][0]); 101 $calls[$i][1][1] = $this->_convert($calls[$i][1][1]); 102 $calls[$i][2] = $this->_convert($calls[$i][2]); 103 } else { 104// $calls[$i][2] = $this->_convert($calls[$i][2]); 105 } 106 } 107 } 108 109 /** 110 * convert modified raw wiki offset value ($pos) back to the unmodified value 111 */ 112 function _convert($pos) { 113 global $debug; 114 115 // file start values will still be file start values - don't change them 116 if ($pos <= 1) return $pos; 117 118 $pos -= $this->base_delta; 119 if ($pos < 0) return 0; 120 121 // simplify access to the conversion data 122 $conversion =& $this->linebreak_conversions[$this->current_marker]; 123 124 for ($i=0; $i<count($conversion); $i++) { 125 // the conversion contains the original source position 126 // we need to add in the modifications up to that point and compare against $pos 127 // remembering we have already modified $pos for the marker string we added first 128 if ($conversion[$i] + $i >= $pos) { 129 return $pos - $i; 130 } 131 } 132 133 // $i will be one more than the number of modifications made 134 return $pos - $i -1; 135 } 136 137} 138 139//Setup VIM: ex: et ts=4 enc=utf-8 :