1<?php
2/**
3 * Footnotetypo - Modify the typography of footenotes
4 * @author Viktor Söderqvist <viktor@zuiderkwast.se>
5 */
6
7 // must be run within Dokuwiki
8if(!defined('DOKU_INC')) die();
9
10// we inherit from the XHTML renderer instead directly of the base renderer
11require_once DOKU_INC.'inc/parser/xhtml.php';
12
13/**
14 * Footnotetypo renderer
15 */
16class renderer_plugin_footnotestyle extends Doku_Renderer_xhtml {
17
18    /**
19     * the format we produce
20     */
21    function getFormat(){
22        return 'xhtml';
23    }
24
25    /**
26     * This makes it possible to use as the default xhtml renderer
27     */
28    function canRender($format) {
29      return ($format=='xhtml');
30    }
31
32    /**
33     * Callback for footnote end syntax
34     *
35     * All rendered content is moved to the $footnotes array and the old
36     * content is restored from $store again
37     *
38     * @author Andreas Gohr
39     * @author Viktor Söderqvist
40     */
41    function footnote_close() {
42
43        // recover footnote into the stack and restore old content
44        $footnote = $this->doc;
45        $this->doc = $this->store;
46        $this->store = '';
47        $amal = $this->getConf('amalgamate');
48        if ($amal != 'off') {
49          // check to see if this footnote has been seen before
50          $i = array_search($footnote, $this->footnotes);
51
52          if ($i === false) {
53              // its a new footnote, add it to the $footnotes array
54              $id = count($this->footnotes)+1;
55              $this->footnotes[count($this->footnotes)] = $footnote;
56          } else {
57              // seen this one before, translate the index to an id and save a placeholder
58              $i++;
59              $id = count($this->footnotes)+1;
60              $this->footnotes[count($this->footnotes)] = "@@FNT".($i);
61          }
62        } else {
63          // don't use amalgamated footnotes.
64          // every note is considered a new footnote. add it to the $footnotes array
65          $id = count($this->footnotes)+1;
66          $this->footnotes[count($this->footnotes)] = $footnote;
67        }
68
69        // output the footnote reference and link
70        $this->doc .= $this->_format_footnote_link($id);
71    }
72
73    /**
74     * Some modification to the document_end regarding the footnotes
75     */
76    function document_end() {
77        if ( count ($this->footnotes) > 0 ) {
78            $this->doc .= '<div class="footnotes">'.DOKU_LF;
79
80            $id = 0;
81            foreach ( $this->footnotes as $footnote ) {
82                $id++;   // the number of the current footnote
83
84                // check its not a placeholder that indicates actual footnote text is elsewhere
85                if (substr($footnote, 0, 5) != "@@FNT") {
86
87                    // open the footnote and set the anchor and backlink
88                    $this->doc .= '<div class="fn">';
89                    $this->doc .= $this->_format_footnote_bottomlink($id);
90
91                    $amal = $this->getConf('amalgamate');
92                    if ('off' != $amal) {
93                        // get any other footnotes that use the same markup
94                        $alt = array_keys($this->footnotes, "@@FNT$id");
95
96                        if (count($alt)) {
97                            foreach ($alt as $ref) {
98                                // set anchor and backlink for the other footnotes
99                                if ($amal=='comma')
100                                    $this->doc .= ', ';
101                                elseif ($amal=='spacecomma')
102                                    $this->doc .= ' '.DOKU_LF.', '; // dw original
103                                else
104                                    $this->doc .= DOKU_LF;
105                                $this->doc .= $this->_format_footnote_bottomlink($ref+1);
106                            }
107                        }
108                    }
109
110                    if ($this->getConf('stylebottom') == 'dot')
111                        $this->doc .= '.';
112
113                    $this->doc .= DOKU_LF;
114
115                    // add footnote markup and close this footnote
116                    $this->doc .= $footnote;
117                    $this->doc .= '</div>' . DOKU_LF;
118                }
119            }
120            $this->doc .= '</div>'.DOKU_LF;
121        }
122
123        // Prepare the TOC
124        global $conf;
125        if($this->info['toc'] && is_array($this->toc) && $conf['tocminheads'] && count($this->toc) >= $conf['tocminheads']){
126            global $TOC;
127            $TOC = $this->toc;
128        }
129
130        // make sure there are no empty paragraphs
131        $this->doc = preg_replace('#<p>\s*</p>#','',$this->doc);
132    }
133
134
135    function _format_footnote_link($id) {
136        $style = $this->getConf('style');
137
138        // the number of the footnote
139        $link = $id;
140
141        // formatting around the number
142        if ($style=='square' || $style=='supersquare')
143            $link = '['.$link.']';
144        elseif ($style=='rightparen')
145            $link .= ')';
146
147        // the link itself
148        $link = '<a href="#fn__'.$id.'" name="fnt__'.$id.'" id="fnt__'.$id.'" class="fn_top">'.$link.'</a>';
149
150        // superscript around the link
151        if ($style=='super' || $style=='rightparen' || $style=='supersquare')
152            $link = '<sup>'.$link.'</sup>';
153
154        return $link;
155    }
156
157    function _format_footnote_bottomlink($id) {
158        $style = $this->getConf('stylebottom');
159
160        $link = $id;
161
162        if ($style=='superrightparen')
163          $link .= ')';
164        elseif ($style=='square' || $style=='supersquare')
165          $link = '['.$link.']';
166
167        $link = '<a href="#fnt__'.$id.'" id="fn__'.$id.'" name="fn__'.$id.'" class="fn_bot">'.$link.'</a>';
168
169        if ($style=='super' || $style=='superrightparen' || $style=='supersquare'){
170          $link = '<sup>'.$link.'</sup>';
171        }else{
172          $link = '<span class="fn_bot_wrapper">'.$link.'</span>';
173        }
174        return $link;
175    }
176}
177
178