1<?php
2
3/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5/**
6 * DokuWiki Plugin bibtex4dw (Syntax Component)
7 *
8 * Parse <bibtex>...</bibtex> blocks in xhtml mode.bibtex
9 *
10 * For parsing the citation commands (i.e., actual references to the literature)
11 * see the file "cite.php".
12 *
13 * PHP versions 5, 7 and 8
14 *
15 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
16 * @author  Till Biskup <till@till-biskup.de>
17 * @version 0.2
18 * @date    2023-05-28
19 */
20
21// must be run within Dokuwiki
22if (!defined('DOKU_INC')) die();
23
24if (!defined('DOKU_LF')) define('DOKU_LF', "\n");
25if (!defined('DOKU_TAB')) define('DOKU_TAB', "\t");
26if (!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC.'lib/plugins/');
27
28require_once DOKU_PLUGIN.'syntax.php';
29
30class syntax_plugin_bibtex4dw_bibtex extends DokuWiki_Syntax_Plugin {
31    public function getType() {
32        return 'protected';
33    }
34
35    public function getPType() {
36        return 'block';
37    }
38
39    public function getSort() {
40        return 32;
41    }
42
43    public function connectTo($mode) {
44        $this->Lexer->addEntryPattern('<bibtex(?=.*?>.*?</bibtex>)', $mode, 'plugin_bibtex4dw_bibtex');
45    }
46
47    public function postConnect() {
48        $this->Lexer->addExitPattern('</bibtex>', 'plugin_bibtex4dw_bibtex');
49    }
50
51    public function handle($match, $state, $pos, Doku_Handler $handler){
52        if ($state == DOKU_LEXER_UNMATCHED) {
53            // $matches[0] is the parameters <bibtex [parameters]>
54            // $matches[1] is the text inside the block <bibtex [parameters]> </bibtex>
55            $matches = preg_split('/>/u', $match, 2);
56            $matches[0] = trim($matches[0]);
57            if ( trim($matches[0]) == '' ) {
58                $matches[0] = NULL;
59            }
60            return array($state, $matches[0], $matches[1], $pos);
61        }
62        return array($state, '', $match, $pos);
63    }
64
65    public function render($mode, Doku_Renderer $renderer, $data) {
66        global $ID;
67        if($mode == 'xhtml') {
68
69            list($state, $substate, $match, $pos) = $data;
70
71            switch ($state) {
72
73                case DOKU_LEXER_ENTER:
74                    break;
75
76                case DOKU_LEXER_UNMATCHED:
77                    require_once(DOKU_PLUGIN.'bibtex4dw/lib/bibtexrender.php');
78                    $bibtexrenderer = bibtexrender_plugin_bibtex4dw::getResource($ID);
79
80                    // Handle special substate "database" already here
81                    if ($substate === 'database') {
82                        $bibtexrenderer->addBibtexToSQLite($match, $ID);
83                        $renderer->doc .= '<pre class="bibtex_database">';
84                        // return the dokuwiki markup within the bibtex tags
85                        $renderer->doc .= $renderer->_xmlEntities($match);
86                        $renderer->doc .= '</pre>';
87                        break;
88                    }
89
90                    // split $match line by line
91                    $matches = preg_split("/\r?\n/", trim($match));
92                    $options = array();
93                    // Add key-value pairs into options array
94                    foreach ($matches as $option) {
95                        if ($option == trim($match)) {
96                            continue; // No match => preg_split returns its input as only array element
97                        }
98                        $opt = explode('=', $option, 2);
99                        $options[$opt[0]][] = $opt[1];
100                    }
101
102                    switch ($substate) {
103                        case 'bibliography':
104                            // Careful with options settings, as there are only very
105                            // few options that do make sense to be set that late.
106                            if (array_key_exists('sort', $options)) {
107                                $oopt['sort'] = $options['sort'];
108                            }
109                            if (array_key_exists('nocite', $options)) {
110                                $oopt['nocite'] = $options['nocite'];
111                            }
112                            if (!empty($oopt)) {
113                                $bibtexrenderer->setOptions($oopt);
114                            }
115                            $bibtex = $bibtexrenderer->printBibliography($substate);
116                            $renderer->doc .= $bibtex;
117                            break;
118                        case 'furtherreading':
119                            $bibtexrenderer->setOptions($options);
120                            $bibtex = $bibtexrenderer->printBibliography($substate);
121                            $renderer->doc .= $bibtex;
122                            break;
123                        default:
124                            $bibtexrenderer->setOptions($options);
125                            break;
126                    }
127                    break;
128
129                case DOKU_LEXER_EXIT:
130                    break;
131
132            }
133
134            return true;
135        }
136
137        if($mode == 'odt') {
138
139            list($state, $substate, $match, $pos) = $data;
140
141            switch ($state) {
142
143                case DOKU_LEXER_ENTER :
144                    break;
145
146                case DOKU_LEXER_UNMATCHED :
147                    break;
148
149                case DOKU_LEXER_EXIT :
150                    break;
151
152            }
153
154            return true;
155        }
156
157        return false;
158    }
159
160}
161?>
162