<?php if (!defined('PmWiki')) exit(); /** footnote2.php * Handle footnotes in a page. * * Various modifications by Said Achmiz (2017–2025). * * AWColley 2007-08-05 -- created footnote.php * Extracted from extendmarkup.php Version 2.0.59 * (see http://www.pmwiki.org/wiki/Cookbook/MarkupExtensions) * * Copyright 2007 A. W. Colley * You may use this file however you see fit. I don't care. * * Modified by Randy Brown to work with PHP 5.5 and to omit the blue line if no * footnote is on the page. This allows a group footer to include [^#^] to show * any footnotes present, without showing a blue line if there are none. * * ExtendedMarkup.php Copyright 2004-2006 John Rankin (john.rankin@affinity.co.nz) * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published * by the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * THIS SOFTWARE IS PROVIDED AS IS WITHOUT ANY GUARANTEES FOR SUITABLILITY FOR * ANY PURPOSE. THE COPYRIGHT HOLDERS ARE NOT RESPONSIBLE FOR ANY DAMAGES, WHETHER * DIRECT, INDIRECT, OR TOTALLY UNRELATED THAT MAY ACCOMPANY, RESULT FROM, OR FOR * ANY REASON OCCUR AFTER THE USE OF, PERUSAL OF, OR THINKING ABOUT THIS SOFTWARE. * * If you don’t like the thin blue line, change it in the * `div.footnotes-with-start-line` style below; or, to disable it entirely, * set $FootnoteBlockStartLine to false; or use the [^@^] alternate markup. * * See https://www.pmwiki.org/wiki/Cookbook/Footnotes for more information. */ $RecipeInfo['Footnotes']['Version'] = '2025-02-16'; $HTMLStylesFmt['Footnotes'] = " div.footnotes-with-start-line::before { content: ''; display: block; width: 12em; border-bottom: 1px solid blue; margin-bottom: 0.75em; } div.footnote { margin: 0; padding-left: 2.5em; font-size: 0.9em; position: relative; } div.footnote .footnote-number { position: absolute; left: 0; width: 2em; text-align: right; } div.footnote .footnote-number::after { content: '.'; } "; SDV($FootnoteBacklinkCharacter, '⇑'); SDV($FootnoteRegExp, '/\[\^(.*?)\^\]/s'); SDV($FootnoteBlockStartLine, true); ## [^footnote text^] or [^#1 footnote text^] or [^#1^] / [^#1 footnote text^] ## [^#^] to list footnotes with blue line, or [^@^] to list them without Markup('[^', '<split', $FootnoteRegExp, 'Footnote'); function Footnote($m) { global $FootnoteBacklinkCharacter, $FootnoteBlockStartLine; static $fngroup = 1, $fncount = 0, $fntext = [ ]; $fn_str = $m[1]; if ($fn_str == "#" || $fn_str == "@") { /* Print all defined footnotes. */ if ($fncount > 0) { $fntext = array_filter($fntext, function ($fn) { return ($fn != '#'); }); ksort($fntext); /* Blue line if ‘#’; no line if ‘@’. (Setting $FootnoteBlockStartLine to false disables blue line even for ‘#’.) */ $footnotes_class = 'footnotes' . ($FootnoteBlockStartLine && $fn_str == "#" ? ' footnotes-with-start-line' : ''); $out = "<div class='{$footnotes_class}'>\n" . implode('', $fntext) . "</div>\n"; } else { /* If we’re here, then a [^#^] or [^@^] has been encountered before any footnotes have been defined. We ignore it. */ $out = ''; } /* Clear all defined footnotes, reset footnote numbering, and increment footnote group number. */ $fntext = [ ]; $fncount = 0; $fngroup++; } else { /* This branch of the conditional means that we’re processing a footnote reference and/or definition. (Note that no footnotes will ever be printed unless we take the other branch at some point.) */ $fncount++; /* If there’s a footnote number specified explicitly, then set the number of the current footnote to that number. If there is, additionally, footnote text provided with the number, then set the footnote text to that (i.e., chop off the number prefix). (If there’s only a number and no text, then this is either a reference to a numbered footnote previously defined inline, OR a reference to a numbered footnote that will later be defined non-inline). */ if (preg_match('/^#([0-9]+)(\s+(.+))?$/s', $fn_str, $fn_str_parts)) { $fncount = $fn_str_parts[1]; $fn_str = (isset($fn_str_parts[2]) ? $fn_str_parts[2] : ''); } /* The CSS ‘id’ attributes of both the in-text footnote link and the footnote block itself include the footnote group and number. */ $fnid = $fngroup . '_' . $fncount; /* If there’s footnote text provided, AND a footnote number is given, AND the footnote of that number has been previously referenced, then output nothing (as this must therefore be a non-inline footnote definition). Otherwise, output the footnote link (as this must be a numbered footnote use without an inline definition; or the first use of a numbered footnote with an an inline definition; or a non-numbered, inline-defined footnote). */ $out = ( isset($fn_str_parts[2]) && isset($fntext[$fncount]) && $fntext[$fncount] == '#') ? '' : ( "<a class='footnote' id='fnr{$fnid}' href='#fn{$fnid}'><sup>" . $fncount . "</sup></a>"); if ($fn_str != '') { /* If there’s footnote text provided, then store the text as the definition of the footnote of the current number (which might be either specified explicitly, or computed by incrementing), for later output. (This could be an inline definition, with or without an explicit number, or else a non-inline definition.) */ $fntext[$fncount] = "<div class='footnote' id='fn$fnid'>\n" . "<span class='footnote-number'>$fncount</span> " . $fn_str . " <a href='#fnr$fnid'>$FootnoteBacklinkCharacter</a>" . "\n</div>"; } else if (!isset($fntext[$fncount])) { /* If there’s no footnote text provided, then record that this footnote number has been referenced. This may be checked later, to identify non-inline numbered footnote definitions (see the definition of $out, above). */ $fntext[$fncount] = '#'; } } return $out; }