1<?php
2  if (!class_exists('syntax_plugin_spreadout')) {
3    if (!defined('DOKU_PLUGIN')) {
4      if (!defined('DOKU_INC')) {
5        define('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/');
6      } // if
7      define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/');
8    } // if
9    // Include parent class:
10    require_once(DOKU_PLUGIN . 'syntax.php');
11
12    /**
13     * <tt>syntax_plugin_spreadout.php</tt>, a PHP class that lets the
14     * traditional amongst us to have double spaces after a sentence.
15     *
16     * <p>
17     * This automatically detects and replaces double spaces after sentences.
18     * Basically, any text that ends with a period ('.'), question mark ('?')
19     * or exclamation point ('!'), with an optional bracket after that
20     * punctuation, followed by two or more regular spaces, will be replaced
21     * with a space followed by a non-breaking space entity ("&nbsp;").  This
22     * makes things "spread out" by adding double space punctuation afterwards.
23     * </p><p>
24     * Before you ask, yes, I am a later generation than millennial.
25     * </p>
26     *
27     * <div class="disclaimer">
28     * This program is free software; you can redistribute it and/or modify
29     * it under the terms of the GNU General Public License as published by
30     * the Free Software Foundation; either
31     * <a href="http://www.gnu.org/licenses/gpl.html">version 3</a> of the
32     * License, or (at your option) any later version.<br>
33     * This software is distributed in the hope that it will be useful,
34     * but WITHOUT ANY WARRANTY; without even the implied warranty of
35     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
36     * See the GNU General Public License for more details.
37     * </div>
38     *
39     * @author <a href="mailto:emb@pobox.com">Emma Bowers</a>
40     * @version v1.0
41     */
42    class syntax_plugin_spreadout extends DokuWiki_Syntax_Plugin {
43
44      /**
45       * Tell the parser whether the plugin accepts syntax mode
46       * <tt>$aMode</tt> within its own markup.
47       *
48       * <p>
49       * This method always returns <tt>FALSE</tt> since no other data
50       * can be nested inside a non-breaking space.
51       * </p>
52       * @param $aMode String The requested syntaxmode.
53       * @return Boolean <tt>FALSE</tt> always.
54       * @public
55       * @see getAllowedTypes()
56       */
57      function accepts($aMode) {
58        return FALSE;
59      } // accepts()
60
61      /**
62       * Connect lookup patterns to lexer.
63       *
64       * @param $aMode String The desired rendermode.
65       * @public
66       * @see render()
67       */
68      function connectTo($aMode) {
69        global $lang;
70
71        // $this->Lexer->addSpecialPattern('(?<=[.\?\!\:]) {2,}', $aMode, 'plugin_spreadout');
72        // $this->Lexer->addSpecialPattern('(?<=[.\?\!\:][\)\]\}\"\']) {2,}', $aMode, 'plugin_spreadout');
73        // $this->Lexer->addSpecialPattern('(?<=[.\?\!\:][\]\}\"\']) {2,}', $aMode, 'plugin_spreadout');
74        $this->Lexer->addSpecialPattern(' {2,}', $aMode, 'plugin_spreadout');
75      } // connectTo()
76
77      /**
78       * Get an associative array with plugin info.
79       *
80       * <p>
81       * The returned array holds the following fields:
82       * <dl>
83       * <dt>author</dt><dd>Author of the plugin</dd>
84       * <dt>email</dt><dd>Email address to contact the author</dd>
85       * <dt>date</dt><dd>Last modified date of the plugin in
86       * <tt>YYYY-MM-DD</tt> format</dd>
87       * <dt>name</dt><dd>Name of the plugin</dd>
88       * <dt>desc</dt><dd>Short description of the plugin (Text only)</dd>
89       * <dt>url</dt><dd>Website with more information on the plugin
90       * (eg. syntax description)</dd>
91       * </dl>
92       * @return Array Information about this plugin class.
93       * @public
94       * @static
95       */
96      function getInfo() {
97        return array (
98          'author' =>	'Emma Bowers',
99          'email' =>	'emb@pobox.com',
100          'date' =>	'2025-07-04',
101          'name' =>	'Spreadout Plugin',
102          'desc' =>	'A simple plugin that allows for two spaces between content sentences if the user types two spaces rather than one.',
103          'url' =>	'http://www.dokuwiki.org/plugin:spreadout');
104      } // getInfo()
105
106      /**
107       * Where to sort in?
108       *
109       * @return Integer <tt>174</tt>.
110       * @public
111       * @static
112       */
113      function getSort() {
114        return 174;
115      } // getSort()
116
117      /**
118       * Get the type of syntax this plugin defines.
119       *
120       * @return String <tt>'substition'</tt> (a mispelled 'substitution').
121       * @public
122       * @static
123       */
124      function getType() {
125        return 'disabled';
126      } // getType()
127
128      /**
129       * Handler to prepare matched data for the rendering process.
130       *
131       * <p>
132       * This implementation does nothing (ignoring the passed
133       * arguments) and just returns the given <tt>$aState</tt>.
134       * </p>
135       *
136       * @param $aMatch String The text matched by the patterns.
137       * @param $aState Integer The lexer state for the match.
138       * @param $aPos Integer The character position of the matched text.
139       * @param $aHandler Object Reference to the Doku_Handler object.
140       * @return Integer The given <tt>$aState</tt> value.
141       * @public
142       * @see render()
143       * @static
144       */
145      function handle($aMatch, $aState, $aPos, Doku_Handler $aHandler) {
146        return $aState;		// nothing more to do here ...
147      } // handle()
148
149      /**
150       * Handle the actual output creation.
151       *
152       * <p>
153       * The method checks for the given <tt>$aMode</tt> and returns
154       * <tt>FALSE</tt> when a mode isn't supported.
155       * <tt>$aRenderer</tt> contains a reference to the renderer object
156       * which is currently handling the rendering.
157       * The contents of <tt>$aData</tt> is the return value of the
158       * <tt>handle()</tt> method.
159       * </p><p>
160       * This implementation ignores the passed <tt>$aFormat</tt>
161       * argument adding a raw UTF-8 character sequence to the
162       * renderer's document.
163       * </p>
164       *
165       * @param $aFormat String The output format to generate.
166       * @param $aRenderer Object A reference to the renderer object.
167       * @param $aData Integer The state value returned by <tt>handle()</tt>.
168       * @return Boolean <tt>TRUE</tt> always.
169       * @public
170       * @see handle()
171       */
172      function render($aFormat, Doku_Renderer $aRenderer, $aData) {
173        if (DOKU_LEXER_SPECIAL == $aData) {
174          $aRenderer->doc .= '&nbsp; ';
175        } // if
176        return TRUE;
177      } // render()
178    } // class syntax_plugin_nbsp
179  } // if
180
181?>
182