root/documentation/trunk/packages/plugins/greenstonedocs/syntax.php @ 30114

Revision 30114, 11.0 KB (checked in by jmt12, 4 years ago)

Updated Greenstone customizations for Detritus, but rearranged to move into separate plugin. Initial checkin of plugins, template, special wiki pages.

Line 
1<?php
2/**
3 *  A plugin to provide compatibility between the marked up text format used
4 *  by the Greenstone Documentation Generation scripts and Dokuwiki
5 *
6 *  Features:
7 *  - hide the <!-- id:XXX --> markers used during translation process
8 *
9 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
10 */
11
12if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
14require_once(DOKU_PLUGIN.'syntax.php');
15
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 */
20class syntax_plugin_greenstonedocs
21extends DokuWiki_Syntax_Plugin
22{
23
24    /** The plugin should only effect pages within this namespace.
25     */
26    private $target_namespace_prefix;
27
28
29    /** @function __construct()
30     */
31    public function __construct()
32    {
33        global $conf;
34
35        $this->target_namespace_prefix = $this->getConf('currentnamespace');
36
37        // Prerequisite testing. Ensure the following list of plugins are also
38        // installed and complain otherwise.
39        if ($this->getConf('checkprereq'))
40        {
41            $prereqs = array_flip(explode(' ', $this->getConf('prerequisiteplugins')));
42            if ($dh = opendir(DOKU_PLUGIN))
43            {
44                while (($file = readdir($dh)) !== false)
45                {
46                    $path = DOKU_PLUGIN . $file;
47                    if (substr($file, 0, 1) != '.' && is_dir($path))
48                    {
49                        if (isset($prereqs[$file]))
50                        {
51                            unset($prereqs[$file]);
52                        }
53                    }
54                }
55                closedir($dh);
56            }
57            if (count($prereqs) > 0)
58            {
59                ksort($prereqs);
60                foreach ($prereqs as $plugin_name => $value)
61                {
62                    msg("The Greenstone Wiki requires the plugin: " . $plugin_name, -1);
63                }
64            }
65            else
66            {
67                $this->_resetConf('checkprereq');
68            }
69        }
70        // Check the plugin configuration and, if checked, proceed to auto-
71        // matically update the internal links within the Greenstone wiki pages
72        // to have a different base namespace
73        if ($this->getConf('updatenamespace'))
74        {
75            // Determine the starting point for the update
76            $base_dir = DOKU_INC . 'data/pages/' . $this->getConf('currentnamespace') . '/';
77            // - ensure trailing : for consistency in namespaces
78            $current_namespace = $this->getConf('currentnamespace');
79            if (strlen($current_namespace) > 0 && substr($current_namespace, -1) != ':')
80            {
81                $current_namespace .= ':';
82            }
83            $old_namespace = $this->getConf('oldnamespace');
84            if (strlen($old_namespace) > 0 && substr($old_namespace, -1) != ':')
85            {
86                $old_namespace .= ':';
87            }
88            // - recursive call to do the actual search and replace
89            $raw_child_namespaces = explode(' ', $this->getConf('childnamespaces'));
90            $child_namespaces = array();
91            foreach ($raw_child_namespaces as $raw_child_namespace)
92            {
93                if (strlen($raw_child_namespace) > 0 && substr($raw_child_namespace, -1) != ':')
94                {
95                    $raw_child_namespace .= ':';
96                }
97                $child_namespaces[] = $raw_child_namespace;
98            }
99            // Begin search
100            $this->_replaceInternalLinkNamespace($base_dir, $old_namespace, $current_namespace, $child_namespaces);
101            // Finally, we reset the configuration option back to off.
102            $this->_resetConf('updatenamespace');
103            // Let users know what has happened
104            msg("Sucessfully performed one-time update of namespace in Greenstone Documentation.", 1);
105        }
106    }
107    /** __construct() **/
108
109
110    /**
111     */
112    function _resetConf($key)
113    {
114        // Reset the configuration option back to off.
115        // - file on disk
116        $config_file_path = DOKU_CONF . 'local.php';
117        $content = file_get_contents($config_file_path);
118        $option_prefix = '$conf[\'plugin\'][\'greenstonedocs\'][\'' . $key . '\']';
119        if (strpos($content, $option_prefix) !== false)
120        {
121            $content = str_replace($option_prefix . ' = 1;',
122                                   $option_prefix . ' = 0;',
123                                   $content);
124        }
125        else
126        {
127            $content .= "\n" . $option_prefix . " = 0;";
128        }
129        file_put_contents($config_file_path, $content);
130        // - in memory cache
131        $conf[$key] = 0;
132    }
133    /** _resetConf($key) **/
134
135
136    /** @function _replaceInternalLinkNamespace()
137     */
138    function _replaceInternalLinkNamespace($dir, $old_namespace, $new_namespace, $child_namespaces)
139    {
140        $files = array();
141        if ($dh = opendir($dir))
142        {
143            while (($file = readdir($dh)) !== false)
144            {
145                if (substr($file, 0, 1) != '.')
146                {
147                    $files[] = $file;
148                }
149            }
150            closedir($dh);
151        }
152        foreach ($files as $file)
153        {
154            $path = $dir . $file;
155            // - continue the recursive search through child directories
156            if (is_dir($path))
157            {
158                $this->_replaceInternalLinkNamespace($path . '/', $old_namespace, $new_namespace, $child_namespaces);
159            }
160            else if (substr($file, -4) == '.txt')
161            {
162                // - none of these files are *that* large, so read them
163                // into memory for processing
164                $page_content = file_get_contents($path);
165                // - we are looking for internal links that contain the
166                // old namespace (or '') followed by an expected child
167                // namespace - and then replace the old namespace
168                $pattern = '/(\[\[)' . $old_namespace . '(' . implode('|', $child_namespaces) . ')(.+?\]\])/';
169                $replace = '${1}'. $new_namespace . '${2}${3}';
170                $replace_count = 0;
171                $page_content = preg_replace($pattern, $replace, $page_content, -1, $replace_count);
172                // - special case: also fix up the mismatched imgcaption tags
173                $pattern = '/(<imgcaption .+?>)(<\/imgcaption>)\s*(\{\{.+?\}\})/s';
174                $replace = '${1}${3}${2}';
175                $page_content = preg_replace($pattern, $replace, $page_content, -1, $replace_count);
176                if ($replace_count > 0)
177                {
178                    file_put_contents($path, $page_content);
179                }
180            }
181        }
182    }
183    /** @function _replaceInternalLinkNamespace() **/
184
185
186    /**
187     * Should return the type of syntax this plugin defines.
188     * - notice that the typo (substition == substitution) is necessary
189     */
190    function getType()
191    {
192        return 'substition';
193    }
194
195    /**
196     * Returns a number used to determine in which order modes are added.
197     */
198    function getSort()
199    {
200        return 0;
201    }
202
203    /**
204     * Connect lookup pattern to lexer.
205     */
206    function connectTo($mode)
207    {
208        $current_full_namespace = getNS(getID('id',true));
209        // Note that the result is FALSE if no match, and should be 0 if name-
210        // space starts with prefix.
211        if (strpos($current_full_namespace, $this->target_namespace_prefix) === 0)
212        {
213            // Hiding the section/translation ID tags in headers
214            $this->Lexer->addSpecialPattern( '^[ \t]*={2,6}\s?<!-- s?id:.+? -->[^\n]+={2,6}[ \t]*(?=\n)', $mode, 'plugin_greenstonedocs');
215            // Hiding the translation ID tags in paragraph text
216            $this->Lexer->addSpecialPattern('<!-- id:[^\s]+ -->', $mode, 'plugin_greenstonedocs');
217            // Hiding the translation ID tags in image captions
218            $this->Lexer->addSpecialPattern('\%!-- id:[^\s]+ --\%', $mode, 'plugin_greenstonedocs');
219        }
220    }
221
222    /**
223     * Handler to prepare matched data for the rendering process.
224     *
225     * <p>
226     * The <tt>$aState</tt> parameter gives the type of pattern
227     * which triggered the call to this method:
228     * </p>
229     * <dl>
230     * <dt>DOKU_LEXER_ENTER</dt>
231     * <dd>a pattern set by <tt>addEntryPattern()</tt></dd>
232     * <dt>DOKU_LEXER_MATCHED</dt>
233     * <dd>a pattern set by <tt>addPattern()</tt></dd>
234     * <dt>DOKU_LEXER_EXIT</dt>
235     * <dd> a pattern set by <tt>addExitPattern()</tt></dd>
236     * <dt>DOKU_LEXER_SPECIAL</dt>
237     * <dd>a pattern set by <tt>addSpecialPattern()</tt></dd>
238     * <dt>DOKU_LEXER_UNMATCHED</dt>
239     * <dd>ordinary text encountered within the plugin's syntax mode
240     * which doesn't match any pattern.</dd>
241     * </dl>
242     * @param $aMatch String The text matched by the patterns.
243     * @param $aState Integer The lexer state for the match.
244     * @param $aPos Integer The character position of the matched text.
245     * @param $aHandler Object Reference to the Doku_Handler object.
246     * @return Integer The current lexer state for the match.
247     * @public
248     * @see render()
249     * @static
250     */
251    function handle($match, $state, $pos, &$handler)
252    {
253        if (preg_match('/wiki/i', $match))
254        {
255            return array($state, $match, array('action'=>'debug',
256                                               'pos'=>$pos));
257        }
258        // Special case for IDs (section and language) in header strings
259        if (preg_match('/={2,6}\s?<!-- (s?id):.+? -->[^\n]+={2,6}/', $match))
260        {
261            //msg("<b>[DEBUG]</b> Title: " . htmlspecialchars($match), 2, '', '', MSG_ADMINS_ONLY);
262            $match = preg_replace('/<!-- sid:.+? -->/', '', $match);
263            $match = preg_replace('/<!-- id:.+? -->/', '', $match);
264            $handler->header($match, $state, $pos);
265            return true;
266        }
267        // any other match gets replaced with empty string
268        return array($state, $match, array('action'=>'erase', 'pos'=>$pos));
269    }
270
271    /**
272     * Handle the actual output creation.
273     *
274     * <p>
275     * The method checks for the given <tt>$aFormat</tt> and returns
276     * <tt>FALSE</tt> when a format isn't supported. <tt>$aRenderer</tt>
277     * contains a reference to the renderer object which is currently
278     * handling the rendering. The contents of <tt>$aData</tt> is the
279     * return value of the <tt>handle()</tt> method.
280     * </p>
281     * @see handle()
282     */
283    function render($mode, &$renderer, $data)
284    {
285        if($mode == 'xhtml')
286        {
287            list($state, $match, $params) = $data;
288            switch ($params['action'])
289            {
290            case 'debug':
291                $renderer->doc .= 'SQUIG-squig-squig';
292                break;
293                // By default we do an erase replace
294            default:
295                $renderer->doc .= '';
296            }
297            return true;
298        }
299        return false;
300    }
301}
302
303//Setup VIM: ex: et ts=4 enc=utf-8 :
304?>
Note: See TracBrowser for help on using the browser.