1<?php 2// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project 3// 4// All Rights Reserved. See copyright.txt for details and a complete list of authors. 5// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details. 6// $Id$ 7 8function wikiplugin_footnote_info() 9{ 10 return [ 11 'name' => tra('Footnote'), 12 'documentation' => 'PluginFootnote', 13 'description' => tra('Create automatically numbered footnotes (together with PluginFootnoteArea)'), 14 'prefs' => ['wikiplugin_footnote'], 15 'body' => tra('The footnote'), 16 'iconname' => 'superscript', 17 'filter' => 'wikicontent', 18 'format' => 'html', 19 'introduced' => 3, 20 'params' => [ 21 'tag' => [ 22 'required' => false, 23 'name' => tra('Tag'), 24 'description' => tra('Tag footnote with unique identifier'), 25 'since' => '15.0', 26 'default' => '', 27 'filter' => 'alnum', 28 'accepted' => tra('One word made of alphanumeric characters'), 29 ], 30 'sameastag' => [ 31 'required' => false, 32 'name' => tra('Same as Tag'), 33 'description' => tra('Tag to existing footnote by its Tag'), 34 'since' => '15.0', 35 'default' => '', 36 'filter' => 'alnum', 37 'accepted' => tra('One word made of alphanumeric characters'), 38 ], 39 'sameas' => [ 40 'required' => false, 41 'name' => tra('Same as'), 42 'description' => tra('Tag to existing footnote number'), 43 'since' => '5.0', 44 'default' => '', 45 'filter' => 'alnum', 46 'accepted' => tra('tag name (since 17) or footnote number'), 47 ], 48 'class' => [ 49 'required' => false, 50 'name' => tra('Class'), 51 'description' => tra('Add class to footnotearea'), 52 'since' => '14.0', 53 'default' => '', 54 'filter' => 'alnumspace', 55 'accepted' => tra('Valid CSS class'), 56 ], 57 'scheme' => [ 58 'required' => false, 59 'name' => tra('Scheme'), 60 'description' => tra('Segregate footnotes by class in footnotearea. Apply different numbering style (optional)'), 61 'since' => '17.0', 62 'default' => '', 63 'filter' => 'text', 64 'accepted' => tra('Scheme strings (ClassName:((Number Style|numStyle))). Multiples may be separated by | (roman-upper:className|decimal)'), 65 ], 66 ] 67 ]; 68} 69 70/** 71 * @param string $data 72 * @param $params 73 * @param int $offset 74 * @param WikiParser_Parsable $context 75 * @return string 76 * @throws Exception 77 * 78 * @see wikiplugin_footnotearea() 79 */ 80function wikiplugin_footnote($data, $params, $offset, $context) 81{ 82 /** @var int $globalId Globally unique number of the next footnote, used for intra-document (anchor) links */ 83 static $globalId = 1; 84 global $prefs; 85 86 $footnotes = &$context->footnotes; 87 $smarty = TikiLib::lib('smarty'); 88 89 // By default, we allow popovers to display the footnote content on mouseover 90 if ( isset($prefs['footnote_popovers']) && $prefs['footnote_popovers'] != 'n' ) { 91 $headerlib = TikiLib::lib('header'); 92 $headerlib->add_jsfile('lib/jquery_tiki/tiki-popovers_for_footnotes.js'); 93 } 94 95 if (! isset($footnotes['lists'])) { // if this is the first time the script has run, initialise 96 $footnotes['count'] = 0; 97 $footnotes['nest'] = 0; 98 $footnotes['tag'] = []; // record of tags and associated footnote numbers 99 $footnotes['lists'] = []; // data for general footnotes 100 $footnotes['lists']['.def.']['listType'] = 'decimal'; // set the default display type for lists 101 } 102 103 if (isset($params['scheme'])) { 104 setScheme($params['scheme']); 105 } 106 107 $data = trim($data); 108 if (! empty($data)) { 109 $footnotes['count']++; // keep a record of how many times footones is called to generate unique id's 110 111 // Create an array of classes to be applied 112 $classes = (isset($params['class'])) ? explode(' ', trim($params["class"])) : []; 113 if ($footnotes['nest'] > 0) { // if we are in a nested footnote, add a nested class 114 $classes[] = 'footnest' . $footnotes['nest']; 115 } 116 117 //set the current list to create 118 $list = '.def.'; // Set the default to illegal class name to prevent conflicts 119 foreach ($classes as $class) { 120 if (isset($footnotes['lists'][$class])) { 121 $list = $class; // set list the the first occurrence, if there happens to be multiplies. 122 break; 123 } 124 } 125 126 // wow, thats a mouth full, lets make it a little more pleasing to the eyes. 127 $footnote = &$footnotes['lists'][$list]['entry']; 128 129 // set the current number of list entries 130 $listNum = count($footnote) + 1; 131 132 if (isset($params["tag"]) && ! isset($footnotes['tag'][$params["tag"]])) { // do nothing if duplicate tag 133 // Keep track of where data can be found for this Tag 134 $footnotes['tag'][$params["tag"]]['class'] = $list; 135 $footnotes['tag'][$params["tag"]]['num'] = $listNum; 136 $footnote[$listNum]['unique'] = $params["tag"]; 137 } else { 138 $footnote[$listNum]['unique'] = $footnotes['count']; 139 } 140 141 $footnote[$listNum]['class'] = implode(' ', $classes); 142 143 $footnotes['nest']++; 144 $footnote[$listNum]['data'] = TikiLib::lib('parser')->parse_data_plugin($data, true); 145 $footnotes['nest']--; 146 147 148 $smarty->assign('uniqueId', $footnote[$listNum]['unique']); 149 $smarty->assign('unique', $footnote[$listNum]['unique']); 150 $smarty->assign('listNum', $listNum); 151 $smarty->assign('class', $footnote[$listNum]['class']); 152 $smarty->assign('listType', $footnotes['lists'][$list]['listType']); 153 return $smarty->fetch('templates/wiki-plugins/wikiplugin_footnote.tpl'); 154 } else { // if there is no data 155 if (isset($params['sameastag'])) { 156 $sameas = $params['sameastag']; 157 } elseif (isset($params['sameas'])) { 158 $sameas = $params['sameas']; 159 } 160 if (isset($sameas)) { 161 if (isset($footnotes['tag'][$sameas])) { 162 $listNum = $footnotes['tag'][$sameas]['num']; 163 $uniqueId = $sameas . '-' . (@count($footnotes['lists'][ $footnotes['tag'][$sameas]['class'] ]['entry'][$listNum]['sameas']) + 1); 164 $footnotes['lists'][$footnotes['tag'][$sameas]['class']]['entry'][$listNum]['sameas'][] = $uniqueId; 165 $smarty->assign('listNum', $listNum); 166 $smarty->assign('uniqueId', $uniqueId); 167 $smarty->assign('unique', $sameas); 168 $smarty->assign('listType', $footnotes['lists'][$footnotes['tag'][$sameas]['class']]['listType']); 169 $smarty->assign('class', $footnotes['lists'][$footnotes['tag'][$sameas]['class']]['entry'][$listNum]['class']); 170 } elseif ((string)(int)$sameas === (string)$sameas) { // else if the value is a integer 171 $smarty->assign('listNum', $sameas);// legacy support for number pointing. 172 $smarty->assign('listType', $footnotes['lists']['.def.']['listType']); 173 if (isset($footnotes['lists']['.def.']['entry'][$sameas])) { // if the entry already exists 174 $uniqueId = $sameas . '-' . (count($footnotes['lists']['.def.']['entry'][$sameas]['sameas']) + 1); 175 $footnotes['lists']['.def.']['entry'][$sameas]['sameas'][] = $uniqueId; 176 $smarty->assign('uniqueId', $uniqueId); 177 $smarty->assign('unique', $footnotes['lists']['.def.']['entry'][$sameas]['unique']); 178 $smarty->assign('class', $footnotes['lists']['.def.']['entry'][$sameas]['class']); 179 } else { // legacy support. These values use to be static 180 $smarty->assign('unique', $sameas); 181 $smarty->assign('uniqueId', ''); 182 $smarty->assign('class', ''); 183 } 184 } else { 185 // The tag does not exist (yet) !!!! 186 return '<sup>' . tra('Error: Tag not found in any previous footnote') . '</sup>'; 187 } 188 return $smarty->fetch('templates/wiki-plugins/wikiplugin_footnote.tpl'); 189 } 190 } 191 192 return ''; 193} 194 195function setScheme($rawScheme) 196{ 197 global $footnotes; 198 $classes = explode('|', $rawScheme); 199 foreach ($classes as $class) { 200 $scheme = explode(':', $class); 201 if (! isset($scheme[1])) { 202 $scheme[1] = '.def.'; // if no class specified, use the default list 203 } 204 $footnotes['lists'][$scheme[1]]['listType'] = $scheme[0]; 205 } 206} 207