-
+ 8E2449D4AC26EA05F080CEC9D025EF8A8585221EE30DA439B37FF1578D084E1C63CBE3F89E3D6868C19D0FA9F73A9AF99B444251E7A854F6C87E316628D94859
mp-wp/wp-content/plugins/footnotes.php
(0 . 0)(1 . 346)
11 <?php
12 /*
13 Plugin Name: WP-Footnotes
14 Plugin URI: http://www.elvery.net/drzax/more-things/wordpress-footnotes-plugin/
15 Version: 4.2
16 Description: Allows a user to easily add footnotes to a post.
17 Author: Simon Elvery
18 Author URI: http://www.elvery.net/drzax/
19 */
20
21 /*
22 * This file is part of WP-Footnotes a plugin for Word Press
23 * Copyright (C) 2007 Simon Elvery
24 *
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * as published by the Free Software Foundation; either version 2
28 * of the License, or (at your option) any later version.
29 *
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
34 *
35 * You should have received a copy of the GNU General Public License
36 * along with this program; if not, write to the Free Software
37 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
38 */
39
40 // Some important constants
41 define('WP_FOOTNOTES_OPEN', " (("); //You can change this if you really have to, but I wouldn't recommend it.
42 define('WP_FOOTNOTES_CLOSE', "))"); //Same with this one.
43 define('WP_FOOTNOTES_VERSION', '4.2');
44
45 // Instantiate the class
46 $swas_wp_footnotes = new swas_wp_footnotes();
47
48 // Encapsulate in a class
49 class swas_wp_footnotes {
50 var $current_options;
51 var $default_options;
52
53 /**
54 * Constructor.
55 */
56 function swas_wp_footnotes() {
57 // Define the implemented option styles
58 $this->styles = array(
59 'decimal' => '1,2...10',
60 'decimal-leading-zero' => '01, 02...10',
61 'lower-alpha' => 'a,b...j',
62 'upper-alpha' => 'A,B...J',
63 'lower-roman' => 'i,ii...x',
64 'upper-roman' => 'I,II...X',
65 'symbol' => 'Symbol'
66 );
67
68 // Define default options
69 $this->default_options = array('superscript'=>true,
70 'pre_backlink'=>' [',
71 'backlink'=>'↩',
72 'post_backlink'=>']',
73 'pre_identifier'=>'',
74 'list_style_type'=>'decimal',
75 'list_style_symbol'=>'†',
76 'post_identifier'=>'',
77 'pre_footnotes'=>'',
78 'post_footnotes'=>'',
79 'style_rules'=>'ol.footnotes{font-size:0.8em; color:#666666;}',
80 'no_display_home'=>false,
81 'no_display_archive'=>false,
82 'no_display_date'=>false,
83 'no_display_category'=>false,
84 'no_display_search'=>false,
85 'no_display_feed'=>false,
86 'combine_identical_notes'=>false,
87 'priority'=>11,
88 'version'=>WP_FOOTNOTES_VERSION);
89
90 // Get the current settings or setup some defaults if needed
91 if (!$this->current_options = get_option('swas_footnote_options')){
92 $this->current_options = $this->default_options;
93 update_option('swas_footnote_options', $this->current_options);
94 } else {
95 // Set any unset options
96 if ($this->current_options['version'] != WP_FOOTNOTES_VERSION) {
97 foreach ($this->default_options as $key => $value) {
98 if (!isset($this->current_options[$key])) {
99 $this->current_options[$key] = $value;
100 }
101 }
102 $this->current_options['version'] = WP_FOOTNOTES_VERSION;
103 update_option('swas_footnote_options', $this->current_options);
104 }
105 }
106
107 /*
108 if (!empty($_POST['save_options'])){
109 $footnotes_options['superscript'] = (array_key_exists('superscript', $_POST)) ? true : false;
110 $footnotes_options['pre_backlink'] = $_POST['pre_backlink'];
111 $footnotes_options['backlink'] = $_POST['backlink'];
112 $footnotes_options['post_backlink'] = $_POST['post_backlink'];
113 $footnotes_options['pre_identifier'] = $_POST['pre_identifier'];
114 $footnotes_options['list_style_type'] = $_POST['list_style_type'];
115 $footnotes_options['post_identifier'] = $_POST['post_identifier'];
116 $footnotes_options['list_style_symbol'] = $_POST['list_style_symbol'];
117 $footnotes_options['pre_footnotes'] = stripslashes($_POST['pre_footnotes']);
118 $footnotes_options['post_footnotes'] = stripslashes($_POST['post_footnotes']);
119 $footnotes_options['style_rules'] = stripslashes($_POST['style_rules']);
120 $footnotes_options['no_display_home'] = (array_key_exists('no_display_home', $_POST)) ? true : false;
121 $footnotes_options['no_display_archive'] = (array_key_exists('no_display_archive', $_POST)) ? true : false;
122 $footnotes_options['no_display_date'] = (array_key_exists('no_display_date', $_POST)) ? true : false;
123 $footnotes_options['no_display_category'] = (array_key_exists('no_display_category', $_POST)) ? true : false;
124 $footnotes_options['no_display_search'] = (array_key_exists('no_display_search', $_POST)) ? true : false;
125 $footnotes_options['no_display_feed'] = (array_key_exists('no_display_feed', $_POST)) ? true : false;
126 $footnotes_options['combine_identical_notes'] = (array_key_exists('combine_identical_notes', $_POST)) ? true : false;
127 $footnotes_options['priority'] = $_POST['priority'];
128 update_option('swas_footnote_options', $footnotes_options);
129 }elseif(!empty($_POST['reset_options'])){
130 update_option('swas_footnote_options', '');
131 update_option('swas_footnote_options', $this->default_options);
132 }
133 */
134
135 // Hook me up
136 add_action('the_content', array($this, 'process'), $this->current_options['priority']);
137 add_action('admin_menu', array($this, 'add_options_page')); // Insert the Admin panel.
138 add_action('wp_head', array($this, 'insert_styles'));
139 }
140
141 /**
142 * Searches the text and extracts footnotes.
143 * Adds the identifier links and creats footnotes list.
144 * @param $data string The content of the post.
145 * @return string The new content with footnotes generated.
146 */
147 function process($data) {
148 global $post;
149
150 // Check for and setup the starting number
151 $start_number = (preg_match("|<!\-\-startnum=(\d+)\-\->|",$data,$start_number_array)==1) ? $start_number_array[1] : 1;
152
153 // Regex extraction of all footnotes (or return if there are none)
154 if (!preg_match_all("/(".preg_quote(WP_FOOTNOTES_OPEN)."|<footnote>)(.*)(".preg_quote(WP_FOOTNOTES_CLOSE)."|<\/footnote>)/Us", $data, $identifiers, PREG_SET_ORDER)) {
155 return $data;
156 }
157
158 // Check whether we are displaying them or not
159 $display = true;
160 if ($this->current_options['no_display_home'] && is_home()) $display = false;
161 if ($this->current_options['no_display_archive'] && is_archive()) $display = false;
162 if ($this->current_options['no_display_date'] && is_date()) $display = false;
163 if ($this->current_options['no_display_category'] && is_category()) $display = false;
164 if ($this->current_options['no_display_search'] && is_search()) $display = false;
165 if ($this->current_options['no_display_feed'] && is_feed()) $display = false;
166
167 $footnotes = array();
168
169 // Check if this post is using a different list style to the settings
170 if ( array_key_exists(get_post_meta($post->ID, 'footnote_style', true), $this->styles) ) {
171 $style = get_post_meta($post->ID, 'footnote_style', true);
172 } else {
173 $style = $this->current_options['list_style_type'];
174 }
175
176 // Create 'em
177 for ($i=0; $i<count($identifiers); $i++){
178 // Look for ref: and replace in identifiers array.
179 if (substr($identifiers[$i][2],0,4) == 'ref:'){
180 $ref = (int)substr($identifiers[$i][2],4);
181 $identifiers[$i]['text'] = $identifiers[$ref-1][2];
182 }else{
183 $identifiers[$i]['text'] = $identifiers[$i][2];
184 }
185
186
187 // if we're combining identical notes check if we've already got one like this & record keys
188 if ($this->current_options['combine_identical_notes']){
189 for ($j=0; $j<count($footnotes); $j++){
190 if ($footnotes[$j]['text'] == $identifiers[$i]['text']){
191 $identifiers[$i]['use_footnote'] = $j;
192 $footnotes[$j]['identifiers'][] = $i;
193 break;
194 }
195 }
196 }
197
198 if (!isset($identifiers[$i]['use_footnote'])){
199 // Add footnote and record the key
200 $identifiers[$i]['use_footnote'] = count($footnotes);
201 $footnotes[$identifiers[$i]['use_footnote']]['text'] = $identifiers[$i]['text'];
202 $footnotes[$identifiers[$i]['use_footnote']]['symbol'] = $identifiers[$i]['symbol'];
203 $footnotes[$identifiers[$i]['use_footnote']]['identifiers'][] = $i;
204 }
205 }
206
207 // Footnotes and identifiers are stored in the array
208 $use_full_link = false;
209
210 if (is_feed()) $use_full_link = true;
211
212 if (is_preview()) $use_full_link = false;
213
214 // Display identifiers
215 foreach ($identifiers as $key => $value) {
216 $id_id = "identifier_".$key."_".$post->ID;
217 $id_num = ($style == 'decimal') ? $value['use_footnote']+$start_number : $this->convert_num($value['use_footnote']+$start_number, $style, count($footnotes));
218 $id_href = ( ($use_full_link) ? get_permalink($post->ID) : '' ) . "#footnote_".$value['use_footnote']."_".$post->ID;
219
220 // $id_title = str_replace('"', """, htmlentities(strip_tags($value['text']), ENT_QUOTES, 'UTF-8'));
221
222 $id_title = str_replace('"', '`', strip_tags($value['text']));
223 $id_replace = $this->current_options['pre_identifier'].'<a href="'.$id_href.'" id="'.$id_id.'" class="footnote-link footnote-identifier-link" title="'.$id_title.'">'.$id_num.'</a>'.$this->current_options['post_identifier'];
224 if ($this->current_options['superscript']) $id_replace = '<sup>'.$id_replace.'</sup>';
225 if ($display) $data = substr_replace($data, $id_replace, strpos($data,$value[0]),strlen($value[0]));
226 else $data = substr_replace($data, '', strpos($data,$value[0]),strlen($value[0]));
227 }
228
229 // Display footnotes
230 if ($display) {
231 $start = ($start_number != 1) ? 'start="'.$start_number.'" ' : '';
232 $data = $data.$this->current_options['pre_footnotes'];
233
234 $data = $data . '<ol '.$start.'class="footnotes">';
235 foreach ($footnotes as $key => $value) {
236 $data = $data.'<li id="footnote_'.$key.'_'.$post->ID.'" class="footnote"';
237 if ($style == 'symbol') {
238 $data = $data . ' style="list-style-type:none;"';
239 } elseif($style != $this->current_options['list_style_type']) {
240 $data = $data . ' style="list-style-type:' . $style . ';"';
241 }
242 $data = $data . '>';
243 if ($style == 'symbol') {
244 $data = $data . '<span class="symbol">' . $this->convert_num($key+$start_number, $style, count($footnotes)) . '</span> ';
245 }
246 $data = $data.$value['text'];
247 if (!is_feed()){
248 foreach($value['identifiers'] as $identifier){
249 $data = $data.$this->current_options['pre_backlink'].'<a href="'.( ($use_full_link) ? get_permalink($post->ID) : '' ).'#identifier_'.$identifier.'_'.$post->ID.'" class="footnote-link footnote-back-link">'.$this->current_options['backlink'].'</a>'.$this->current_options['post_backlink'];
250 }
251 }
252 $data = $data . '</li>';
253 }
254 $data = $data . '</ol>' . $this->current_options['post_footnotes'];
255 }
256 return $data;
257 }
258
259 /**
260 * Really insert the options page.
261 */
262 function footnotes_options_page() {
263 $this->current_options = get_option('swas_footnote_options');
264 foreach ($this->current_options as $key=>$setting) {
265 $new_setting[$key] = htmlentities($setting);
266 }
267 $this->current_options = $new_setting;
268 unset($new_setting);
269 include (dirname(__FILE__) . '/options.php');
270 }
271
272 /**
273 * Insert the options page into the admin area.
274 */
275 function add_options_page() {
276 // Add a new menu under Options:
277 add_options_page('Footnotes', 'Footnotes', 8, __FILE__, array($this, 'footnotes_options_page'));
278 }
279
280 function upgrade_post($data){
281 $data = str_replace('<footnote>',WP_FOOTNOTES_OPEN,$data);
282 $data = str_replace('</footnote>',WP_FOOTNOTES_CLOSE,$data);
283 return $data;
284 }
285
286 function insert_styles(){
287 ?>
288 <style type="text/css">
289 <?php if ($this->current_options['list_style_type'] != 'symbol'): ?>
290 ol.footnotes li {list-style-type:<?php echo $this->current_options['list_style_type']; ?>;}
291 <?php endif; ?>
292 <?php echo $this->current_options['style_rules'];?>
293 </style>
294 <?php
295 }
296
297
298 function convert_num ($num, $style, $total){
299 switch ($style) {
300 case 'decimal-leading-zero' :
301 $width = max(2, strlen($total));
302 return sprintf("%0{$width}d", $num);
303 case 'lower-roman' :
304 return $this->roman($num, 'lower');
305 case 'upper-roman' :
306 return $this->roman($num);
307 case 'lower-alpha' :
308 return $this->alpha($num, 'lower');
309 case 'upper-alpha' :
310 return $this->alpha($num);
311 case 'symbol' :
312 $sym = '';
313 for ($i = 0; $i<$num; $i++) {
314 $sym .= $this->current_options['list_style_symbol'];
315 }
316 return $sym;
317 }
318 }
319
320
321 /**
322 * Convert to a roman numeral.
323 *
324 * Thanks to Indi.in.the.Wired for the improved algorithm.
325 * http://plugins.trac.wordpress.org/ticket/1177
326 *
327 * @param int $num The number to convert.
328 * @param string $case Upper or lower case.
329 * @return string The roman numeral
330 */
331 function roman($num, $case= 'upper'){
332 $num = (int) $num;
333 $conversion = array('M'=>1000, 'CM'=>900, 'D'=>500, 'CD'=>400, 'C'=>100, 'XC'=>90, 'L'=>50, 'XL'=>40, 'X'=>10, 'IX'=>9, 'V'=>5, 'IV'=>4, 'I'=>1);
334 $roman = '';
335
336 foreach ($conversion as $r => $d){
337 $roman .= str_repeat($r, (int)($num / $d));
338 $num %= $d;
339 }
340
341 return ($case == 'lower') ? strtolower($roman) : $roman;
342 }
343
344 function alpha($num, $case='upper'){
345 $j = 1;
346 for ($i = 'A'; $i <= 'ZZ'; $i++){
347 if ($j == $num){
348 if ($case == 'lower')
349 return strtolower($i);
350 else
351 return $i;
352 }
353 $j++;
354 }
355 }
356 }