Table of Contents

linebreak Plugin

Compatible with DokuWiki

Weatherwax

plugin Generate line breaks in output for line breaks in raw wiki data

Last updated on
2007-01-20
Provides
Syntax, Action

This extension has not been updated in over 2 years. It may no longer be maintained or supported and may have compatibility issues.

Tagged with !experimental, typography

experimental

Use xbr rather than linebreak. xbr is a render plugin and replaces the way the DokuWiki renders ordinary text to preserve line breaks.
Linebreak is a hack from the time before render plugins were possible.
Its reported not to work (at least in some wikis) with the latest version of DokuWiki. I won't be updating it.

- Chris
(author of both xbr and linebreak plugins)

:!: Packages updated to include functions missing from 2006-03-09 DokuWiki.

This plugin changes the way DokuWiki treats single line break in the raw wiki text - instead of the default behaviour, where the line break is absorbed, it will generate a line break in the HTML output.

This plugin maybe useful for wiki pages which include poetry, song lyrics or other content which is naturally written with meaningful single line breaks.

Syntax

The plugin will recognize single line breaks in the wiki page.

The plugin also supports two directives which can turn on and turn off generation of line breaks in the output HTML.

Installation

Plugin sources:

If your wiki uses either the plugin manager or the darcs plugin you can use them with the appropriate links above to install the plugin.

To install the plugin manually, download the source to your plugin folder, lib/plugins, and extract its contents. That will create a new plugin folder, lib/plugins/linebreak, and install the plugin.

The folder will contain:

syntax.php                            ; plugin script
conf/default.php                      ; default configuration setting values
conf/metadata.php                     ; information for the configuration settings page
lang/xx/settings.php                  ; language strings for configuration settings page

The plugin is now installed.

Configuration

The plugin has two configuration settings:

You can override the default values by either modifying lib/plugins/linebreak/conf/default.php or by adding the setting to your DokuWiki installation local configuration file, conf/local.php. If adding a setting to your local.php, use the following format:

$conf['plugin']['linebreak']['<setting name>'] = <new value>;

Depending on your DokuWiki version you may be able to edit these settings from within the Configuration Settings via the admin menu.

Details

The plugin consists of five files, only the plugin scripts, syntax.php & action.php, are shown here.

syntax.php

<?php
/**
 * Plugin Linebreak: Inserts a line break
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */
 
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
 
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class syntax_plugin_linebreak extends DokuWiki_Syntax_Plugin {
 
    var $no_quotes = array(300, '(?<!^|\n)\n(?!\n)');
    var $in_quotes = array(100, '(?<!^|\n)\n(?!\n|>)');
#    var $no_quotes = array(300, '(?<!\n)\n(?!\n)');
#    var $in_quotes = array(100, '(?<!\n)\n(?!\n|>)');
    var $ptn_pageon = '~~LINEBREAK~~';
    var $ptn_pageoff = '~~NOLINEBREAK~~';
 
    function getInfo(){
      return array(
        'author' => 'Christopher Smith',
        'email'  => 'chris@jalakai.co.uk',
        'date'   => '2007-01-20',
        'name'   => 'Linebreak Plugin',
        'desc'   => 'Provide a line break for a new line in the raw wiki data',
        'url'    => 'http://www.dokuwiki.org/plugin:linebreak',
      );
    }
 
    function getType() { return 'substition'; }
    function getSort() { return ($this->getConf('in_quotes') ? $this->in_quotes[0] : $this->no_quotes[0]); }
    function connectTo($mode) {
 
       $ptn = $this->getConf('in_quotes') ?  $this->in_quotes[1] : $this->no_quotes[1];
       $this->Lexer->addSpecialPattern($ptn,$mode,'plugin_linebreak');
 
       $this->Lexer->addSpecialPattern($this->ptn_pageon,$mode,'plugin_linebreak');
       $this->Lexer->addSpecialPattern($this->ptn_pageoff,$mode,'plugin_linebreak');
 
       $this->Lexer->addSpecialPattern('~~LINEBREAK#.+~~\n',$mode,'plugin_linebreak');
    }
 
    function handle($match, $state, $pos, &$handler){ 
 
      if (substr($match, 0, 12) == '~~LINEBREAK#') {
        $marker = substr($match, 12,-3);
        return array('marker' => $marker);
      }
 
      if (!isset($handler->status['plugin_linebreak'])) {
        $handler->status['plugin_linebreak'] = $this->getConf('automatic');
      }
 
      if ($match == "\n") return array($handler->status['plugin_linebreak']);
 
      if ($match == $this->ptn_pageon) {
        $handler->status['plugin_linebreak'] = true;
      } else if ($match == $this->ptn_pageoff) {
        $handler->status['plugin_linebreak'] = false;
      }
 
      return array(false);
    }
 
    function render($mode, &$renderer, $data) {
 
      if($mode == 'xhtml'){
          if ($data[0]) $renderer->doc .= "<br />";
          return true;
      }
      return false;
    }
 
}

action.php

Note This file is not present in the version of the plugin for DokuWiki release 2006-03-xx. That particular version of DokuWiki precedes action.

<?php
/**
 * Plugin Linebreak: Inserts a line break
 * 
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
 * @author     Christopher Smith <chris@jalakai.co.uk>
 */
 
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
 
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'action.php');
 
/**
 * All DokuWiki plugins to extend the parser/rendering mechanism
 * need to inherit from this class
 */
class action_plugin_linebreak extends DokuWiki_Action_Plugin {
 
    var $marker_id = 0;
    var $linebreak_conversions = array();
 
    /**
     * return some info
     */
    function getInfo(){
      return array(
        'author' => 'Christopher Smith',
        'email'  => 'chris@jalakai.co.uk',
        'date'   => '2007-02-18',
        'name'   => 'Linebreak Plugin',
        'desc'   => 'Provide a line break for a new line in the raw wiki data',
        'url'    => 'http://www.dokuwiki.org/plugin:linebreak',
      );
    }
 
    /**
     * plugin should use this method to register its handlers with the DokuWiki's event controller
     */
    function register(Doku_Event_Handler $controller) {
      $controller->register_hook('PARSER_WIKITEXT_PREPROCESS', 'BEFORE',  $this, '_addspaces', NULL);
      $controller->register_hook('PARSER_HANDLER_DONE','BEFORE', $this, '_fixsecedit', NULL);
    }
 
    /**
     * add spaces before line breaks, required so syntax component pattern will match correctly
     * record the offset changes so we can fix up the section edit offsets later
     */
    function _addspaces(&$event, $param) {
 
      // preg pattern used to find line breaks which require spaces inserted before them
      $pattern = '/(?!< )(\n+|$)/';
 
      // marker to add at the start of the raw wiki data, it contains an id we use to access the location
      // of the additional spaces added into the file
      $marker = "~~LINEBREAK#{$this->marker_id}~~\n";
 
      // get the location (offset) of all the spaces to be added
      $linebreaks = array();
      preg_match_all($pattern, $event->data, $linebreaks, PREG_OFFSET_CAPTURE);
 
      for ($i=0; $i<count($linebreaks[0]); $i++) {
        $conversion[] = $linebreaks[0][$i][1];
      }
 
      // save details of the added spaces
      $this->linebreak_conversions[$this->marker_id] = $conversion;
 
      // add in the spaces
      $event->data = $marker.preg_replace($pattern,' $1',$event->data);
 
      // update the marker id so that the next use gets a fresh id.
      $this->marker_id++;
    }
 
    function _fixsecedit(&$event, $param) {
 
      // find our linebreak marker instruction and get the marker id
      $calls =& $event->data->calls;
      $marker = null;
 
      for ($i=0; $i < count($calls); $i++) {
        if ($calls[$i][0] == 'plugin' && $calls[$i][1][0] == 'linebreak' && isset($calls[$i][1][1]['marker'])) {
          $marker = $calls[$i][1][1]['marker'];
          break;
        }
      }
 
      if (is_null($marker)) return;
 
      // calculate the amount added to the start of the raw wiki data for our marker tag
      $this->base_delta = strlen("~~LINEBREAK#$marker~~\n");
      $this->current_marker = $marker;
 
      // iterate through the instruction list and set the file offset values (usually the $pos variable)
      // back to the values they would be if no spaces had been added by this plugin
      for ($i=0; $i < count($calls); $i++) {
        if ($calls[$i][0] == 'section_edit') {
          $calls[$i][1][0] = $this->_convert($calls[$i][1][0]);
          $calls[$i][1][1] = $this->_convert($calls[$i][1][1]);
          $calls[$i][2] = $this->_convert($calls[$i][2]);
        } else {
//          $calls[$i][2] = $this->_convert($calls[$i][2]);
        }
      }
    }
 
    /**
     *  convert modified raw wiki offset value ($pos) back to the unmodified value
     */
    function _convert($pos) {
      global $debug;
 
      // file start values will still be file start values - don't change them
      if ($pos <= 1) return $pos;
 
      $pos -= $this->base_delta;
      if ($pos < 0) return 0;
 
      // simplify access to the conversion data
      $conversion =& $this->linebreak_conversions[$this->current_marker];
 
      for ($i=0; $i<count($conversion); $i++) {
        // the conversion contains the original source position
        // we need to add in the modifications up to that point and compare against $pos
        // remembering we have already modified $pos for the marker string we added first
        if ($conversion[$i] + $i >= $pos) {
          return $pos - $i;
        }
      }
 
      // $i will be one more than the number of modifications made
      return $pos - $i -1;
    }
 
}
 
//Setup VIM: ex: et ts=4 enc=utf-8 :}

Revision History

To Do

Bugs

:!: Often, when I have the plugin installed: pages will not load, and I get this error:

Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/wiki/lib/plugins/linebreak/action.php on line 98

or

Fatal error: Maximum execution time of 30 seconds exceeded in /var/www/wiki/lib/plugins/linebreak/action.php on line 124

It may have to do with the size of the file. It seem to choke of files over 1300 lines.


Its an unfortunate side-effect of the way the DokuWiki syntax engine works. If I alter things to take care of the circumstance you describe, then the plugin will mess up the normal behaviour of double new lines. You can get around the problem by putting a space after the wiki markup (e.g. "** "). Fixing things would make this very “hacky”. If it is a key issue for many users of the plugin, I'll take a look at what can be done. — Christopher Smith 2006-06-19 11:53
It was quite a surprising behavior for me. I would much prefer there be complexity in my plugin than in my wiki syntax. It's much easier to remember “\n == <br>” than it is to remember “\n == <br>, unless the line ends in markup, in which case <space>\n == <br>”. I want to simplify things for my users.Bill Mill 2006-07-20
comment updated New version released for DokuWiki release candidate including the action plugin which removes the need for spaces after markup – see above. — Christopher Smith 2006-10-18 22:15
Yes. For now, you can either stick to using “Edit Page” rather than “edit section” or stick with the old version of the plugin (requires spaces after DokuWiki syntax codes that appear immediately prior to line endings). — Christopher Smith 2006-12-10 03:53
:!: This problem is now fixed — Christopher Smith 2007-01-20 15:40
The work around is to make sure there is a line break at the end of your page. I'll look into the cause and release a fix asap. — Christopher Smith 2007-02-19 02:32
Fix is a simple change to the pattern used by the action component. I have updated source packages and darcs release. — Christopher Smith 2007-02-19 02:54
Thanks. That seems to work now. When looking at the produced HTML source code I simply wonder why there is always a whitespace before every <br />. When I programmed some PHP I normally put the br tag directly after the last word and added a \n for a newline. But that's just for cosmetics. — eModul 2007-02-25 22:05
The whitespace is added in by the action component to ensure line endings are separated from any DokuWiki syntax by at least one character. Without that separation this plugin won't work. I guess, I could then remove the space in the syntax plugin phase, but it doesn't really seem worth the effort. :-)Christopher Smith 2007-02-26 16:50
Ok. Thanks for clarifying this. I'm happy with it as it is. — eModul 2007-02-28 20:01

Discussion

IMO: DokuWiki should treat linebreaks as linebreaks, and not require a \\ for a linebreak.

  1. requiring a \\ makes it more difficult to move text files into DokuWiki
  2. the source text file looks ugly, cluttered, and unnatural
  3. requiring an invisible character at the end of the \\ means I can not just look at my source text file and tell if there is line break or not.

That said, the I don't know if integrating this plugin would be the best solution. In my experience, this plugin causing longer pages to not load.

Take a look at xbr. It effectively does integrate linebreaks directly into DokuWiki, it uses the newer render plugin type to replace the way DokuWiki handles plain text data. Where as DokuWiki more or less treats single linebreaks as spaces, xbr will replace them with <br /> ensuring the linebreaks are seen as linebreaks on the final web page. It has a lot going for it over this plugin. Its more robust, cleaner & faster. This plugin allows linebreak behaviour to be altered on a page by page basis and even within different areas of a single page. — Christopher Smith 2008/08/25 11:40
I can not figure out how to use or install the xbr plugin.
IMO: the xbr plugin is critically short of basic instruction. A link to the plugin page does not constitute proper documentation.
For example, where does the code specified in the xbr plugin go? /lib/plugins/xbr/syntax.php? lib/plugins/example/renderer.php? Somewhere else?
How do I change the configuration manager so that I can change the renderer_xhtml settings in the configuration file? I suppose I have to edit the canRender() function, but which file? Which directory?
I feel like I would have to second guess, and hit-or-miss every step of the way. This is just too difficult to be worth it.
I've improved its instructions in a comment at the bottom of the page. If they need further improvement, please leave a comment on that page. — Christopher Smith 2008/08/27 03:29

I vote for integration of the plugin into DokuWiki! — Patric Schatzmann 2006-12-05


I find the text syntax of DokuWiki very well, better than Wikipedia. The only thing witch is really ugly is the linebreak handling. Something so basic should a option in the main code and no plugin should by necessarily for this. Why doesn't make inquiry by the users?


Agree, single linebreak in source code should generate a linebreak in HTML result.


Agree even more … my favorite behavior would be to have the described linebreaks for every inserted linebreak and use \\ to turn them off ;)


This broke several other plugins for me (code replacement 2, footnote, etc.). Additionally, it did not uninstall correctly, all wiki pages now have ~~LINEBREAK0~~ or something similar on them. Had to search and delete cache files to remove. – JR 12-06-07


Agree, because a plugin never gets the same support like the main code, and problems with updates, incompatibilities and other plugins are possible. And destruction of source text is a very bad effect. (i had problems with linebreak and had to deactivate it. I use now a patch witch change the main code, and had never problems anymore). 20-12-2007


Agree, please include in main code – GB 10-01-08


Its always my first plugin in all DokuWiki installations :) – sw 10-02-08


+1 to include in main code – VR 06-04-08


Just installed it… LOVE IT, no more backslash backslash space (however, it will take some time to get it out of my system ;-) ) 29-07-2008 MvD


Another vote to include in the main code and/or make it a configuration setting. My users paste a lot of emails into the wiki. Instead of just copy/paste it requires a huge amount of time and effort that really is not needed.. CG 12-2-08


11-09-10 Linebreak plug-in was working very well until I installed the latest version.

Now when pressing 'edit' button at the middle title after the newest version installed, I can correct only a part of it easily, But it is still printing oddly that the upper and lower part of content/context are broken while the linebreak plug-in is on.

How can I bring into same effect as linebreak is on, NOT using
?

example.

Source

====== test ======

Hello, world.

====== temp ======

clicking middle edit button

==

Hello, world.

====== temp =====