xref: /plugin/struct/action/output.php (revision 4ac44d1c588c7d185f6947cfad769552773b541d)
1<?php
2/**
3 * DokuWiki Plugin struct (Action Component)
4 *
5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6 * @author  Andreas Gohr, Michael Große <dokuwiki@cosmocode.de>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12/**
13 * Class action_plugin_struct_output
14 *
15 * This action component handles the automatic output of all schema data that has been assigned
16 * to the current page by appending the appropriate instruction to the handler calls.
17 *
18 * The real output creation is done within the syntax component
19 * @see syntax_plugin_struct_output
20 */
21class action_plugin_struct_output extends DokuWiki_Action_Plugin {
22
23    protected $lastread = '';
24
25    /**
26     * Registers a callback function for a given event
27     *
28     * @param Doku_Event_Handler $controller DokuWiki's event controller object
29     * @return void
30     */
31    public function register(Doku_Event_Handler $controller) {
32        $controller->register_hook('PARSER_HANDLER_DONE', 'AFTER', $this, 'handle_output');
33        $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_read');
34    }
35
36    /**
37     * This is kind of a hack. We want to be sure our instruction is only added when the
38     * instructions of the main page are created. There is no clear way to figure that out
39     * though. Thus we only act on when the appropriate wiki page was read from disk
40     * immediately before our call.
41     *
42     * @param Doku_Event $event
43     * @param $param
44     */
45    public function handle_read(Doku_Event $event, $param) {
46        $this->lastread = cleanID($event->data[1] . ':' . $event->data[2]);
47    }
48
49    /**
50     * Appends the instruction to render our syntax output component to each page
51     * after the first found headline or the very begining if no headline was found
52     *
53     * @param Doku_Event $event
54     * @param $param
55     */
56    public function handle_output(Doku_Event $event, $param) {
57        global $ID;
58        if($this->lastread != $ID) return; // avoid nested calls
59        $this->lastread = '';
60        if(!page_exists($ID)) return;
61
62        $ins = -1;
63        $pos = 0;
64        foreach($event->data->calls as $num => $call) {
65            // try to find the first header
66            if($call[0] == 'header') {
67                $pos = $call[2];
68                $ins = $num;
69                break;
70            }
71
72            // abort when after we looked at the first 150 bytes
73            if($call[3] > 150) {
74                break;
75            }
76        }
77
78        // insert our own call after the found position
79        array_splice(
80            $event->data->calls,
81            $ins+1,
82            0,
83            array(
84                array(
85                    'plugin',
86                    array(
87                        'struct_output', array('pos' => $pos), DOKU_LEXER_SPECIAL, ''
88                    ),
89                    $pos
90                )
91            )
92        );
93    }
94
95}
96
97// vim:ts=4:sw=4:et:
98