{"id":53140,"date":"2021-11-02T06:00:50","date_gmt":"2021-11-02T10:00:50","guid":{"rendered":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=53140"},"modified":"2021-11-02T13:35:21","modified_gmt":"2021-11-02T17:35:21","slug":"about-the-footnotes","status":"publish","type":"post","link":"https:\/\/www.shamusyoung.com\/twentysidedtale\/?p=53140","title":{"rendered":"About The Footnotes&#8230;"},"content":{"rendered":"<p>I recently got an email asking about the footnotes I use on this site. These sorts of questions pop up pretty often. People ask things like: <em>Is there a plugin I can use? Did you come up with the idea yourself? How do you create them?<\/em> The answers to which are No, No, and &#8220;It&#8217;s complicated&#8221;.<\/p>\n<p>As many have suspected, I stole the idea for the footnotes from the XKCD &#8220;<a href=\"https:\/\/what-if.xkcd.com\/96\/\">What-if?<\/a>&#8221; series. I don&#8217;t remember when I first started using them. I just did a quick scan through the archives and found a footnote in a post from 2014, but I&#8217;m not sure how much further back they might go. <\/p>\n<p>Over the years I&#8217;ve become so used to footnotes that I find it annoying to write without them. If I find myself writing a long email, I&#8217;ll usually end up with lots of awkward parenthetical statements that I wish I could turn into footnotes. <\/p>\n<p>Before I had footnotes, I sometimes wrote <em>nested<\/em> parenthetical statements. They were fun to write, but they&#8217;re ugly as hell and very hard on readability.<\/p>\n<p>There weren&#8217;t any footnote plugins available back when I first introduced this feature. I cobbled it together myself by stealing some javascript from the What-if page and making my own version. To get a footnote system working in WordPress you need to do what most modern web developers do and string a bunch of different systems and languages together into a big Rube Goldberg machine.<\/p>\n<p>First is the syntax. You don&#8217;t want to clutter up your articles with tons of complex HTML. So I use a fairly minimalist shortcode that looks like this:<\/p>\n<p><!--more--><tt>Here is an example sentence.&#91;ref|And here is an example footnote.]<\/tt><\/p>\n<p>Is that great syntax? Eh. Probably not. But it&#8217;s what I came up with, and so we&#8217;re stuck with it now. So you put the above text into an article. Then you create a WordPress filter in PHP that will find these tags and turn them into useful HTML.<\/p>\n<pre lang=\"php\">\r\nfunction roller_tag_ref ($text)\r\n{\r\n  global  $reftagnum;\r\n  global  $reftagpost;\r\n  global  $reffootnote;\r\n\r\n  $reftagnum = 1;\r\n  if ($reftagpost != get_the_ID()) {\r\n    $reftagpost = get_the_ID();\r\n    $reftagnum = 1;\r\n  }\r\n  while (1) {\r\n    $tag_start = strpos ($text, \"[ref\");\r\n    if ($tag_start === FALSE)\r\n        return $text;\r\n    $tag_end = strpos ($text, \"]\", $tag_start);\r\n    if ($tag_end === FALSE)\r\n        return $text;\r\n    $tag_length = $tag_end - $tag_start;\r\n    $find = substr ($text, $tag_start, $tag_length + 1);\r\n    $tag = substr ($find, 4, $tag_length - 4);\r\n    $info = explode (\"|\", $tag);\r\n    $reftag = 'INVALID';\r\n    if (count ($info) >= 3) {\r\n      $reftag = $info[1];\r\n      $refbody = $info[2];\r\n    } else if (count ($info) >= 2) {\r\n      $reftag = $reftagnum++;\r\n      $refbody = $info[1];\r\n    } else\r\n      return $text;\r\n    $reftitle = $refbody;\r\n    if (is_feed ())\r\n      $replace = \"<sup>[$reftag]<\/sup>\";\r\n    else\r\n      $replace = \"<span class='snote' title='$reftag'>$reftitle<\/span>\";\r\n    $reffootnote .= \"<p>[$reftag] $reftitle<\/p>\";\r\n    $text = str_replace ($find, $replace, $text);\r\n  }\r\n}\r\n<\/pre>\n<p>That code will take the original sentence and expand it to this:<\/p>\n<p><tt>Here is an example sentence.&lt;span class='snote' title='1'&gt;And here is an example footnote.&lt;\/span&gt;<\/tt><\/p>\n<p>The footnote text is shoved inside of a named <tt>span<\/tt> tag so that we can hide or show it whenever we like. Now, maybe you&#8217;re thinking, &#8220;Hey Shamus. This HTML doesn&#8217;t look that much longer than the shortcode you use above. Is this really necessary?&#8221; <\/p>\n<p>Yes, it is. The code also handles the automatic numbering. I don&#8217;t want to have to re-number all of my footnotes because I decided to add a new one at the top of the article. <\/p>\n<p>Now we need to use CSS to control its appearance&#8230;<\/p>\n<pre lang=\"css\">\r\n.snote_tip\r\n{\r\n  font-size:          smaller;\r\n  display:            inline-block;\r\n  visibility:         hidden;\r\n  position:           absolute;\r\n  overflow:           hidden;\r\n  padding:            0.5em;\r\n  overflow:           auto;\r\n  background:         #fea;\r\n  color:              #000000;\r\n  border:             2px solid #874;\r\n  box-shadow:         0.25em 0.25em 0.25em #555;\r\n  z-index:            1;\r\n  max-width:          50%;\r\n}\r\n\r\n.snote_tip:hover {  cursor: pointer; }\r\n<\/pre>\n<p>We make the font smaller, we make sure the box doesn&#8217;t take up any space in the document, and we do some obvious style stuff like coloring things and adding a drop shadow. Also, we make sure the boxes are hidden by default.<\/p>\n<p>Fine. But now comes the hard part. We need to reveal a box when the user clicks on the number. And for that we need some Javascript. I don&#8217;t know why, but the JS I stole from What-if managed to break after a couple of years. Then a reader sent me this to replace it:<\/p>\n<pre lang=\"javascript\">\r\n\/\/call this function once the page has loaded\r\nwindow.addEventListener('load', snote_init, false);\r\nwindow.addEventListener('mouseup', snote_hide, true);\r\n\r\n\/\/this function will add a span with snote_tip class where a span with the snote class is used, \r\n\/\/this reduces the html needed and makes writing notes so much simpler\/cleaner.\r\nfunction snote_init() {\r\n    var snote_elements = document.getElementsByClassName('snote');\r\n    for (var i = 0; i < snote_elements.length; i += 1) {\r\n      (function(i)  {\r\n        var snote_element = snote_elements[i];\r\n\r\n        snote_element.innerHTML = '<span class=\"snote_refnum\" title=\"\">[' + snote_element.title + ']\r\n        <\/span>' + '<span class=\"snote_tip\" id=\"snote_' + i + '\">' + snote_element.innerHTML + '<\/span>';\r\n        snote_element.style.display = 'inline-block';\r\n        snote_element.addEventListener (\"mouseup\", function () {snote_show(i)}, false);\r\n      })(i);\r\n   }\r\n}\r\n\r\nfunction snote_hide (arg)\r\n{\r\n  var snote_elements = document.getElementsByClassName('snote_tip');\r\n  for (var i = 0; i < snote_elements.length; i += 1) {\r\n    var snote_element = snote_elements[i];\r\n    snote_element.style.visibility = 'hidden';\r\n  }\r\n}\r\n  \r\nfunction snote_show(arg)\r\n{\r\n    var snote_tip = document.getElementById('snote_' + arg);\r\n      \r\n    if (snote_tip.style.visibility == 'visible')  {\r\n      snote_tip.style.visibility = 'hidden';\r\n    } else {\r\n      snote_tip.style.visibility = 'visible';\r\n    }\r\n}\r\n<\/pre>\n<p>And now the system works:<\/p>\n<p>Here is an example sentence.[ref|And here is an example footnote.]<\/p>\n<p>So this system is a Frankenstein's monster of HTML, custom shortcode, PHP, CSS, and Javascript. <\/p>\n<p>It's not perfect. The size and positioning of the text box is left to the browser to decide. That means that if a footnote lands near the right margin, the box might appear slightly off-screen.[ref|This is really only a problem in mobile view, where the text goes right to the edge of the screen. On a desktop, we have decadently large margins that can accommodate footnote boxes that spill out of the main reading area.] <\/p>\n<p>But wait! Before you copy & paste my horrible system to use on your own site, you should probably try <a href=\"https:\/\/wordpress.org\/plugins\/easy-footnotes\/\">this plugin<\/a>. The shortcode isn't as short[ref|It uses opening and closing tags, which makes it more verbose AND it means you can have problems with mismatched tags.] but it's probably ten times easier than rolling your own. I'd use it myself if I didn't have several years of legacy text tying me to my current system. <\/p>\n<p>There, I managed to write 1,000 words about web development and I managed to resist the urge to complain about the awfulness of PHP \/ Javascript. You're welcome.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I recently got an email asking about the footnotes I use on this site. These sorts of questions pop up pretty often. People ask things like: Is there a plugin I can use? Did you come up with the idea yourself? How do you create them? The answers to which are No, No, and &#8220;It&#8217;s [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-53140","post","type-post","status-publish","format-standard","hentry","category-general"],"_links":{"self":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/53140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=53140"}],"version-history":[{"count":16,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/53140\/revisions"}],"predecessor-version":[{"id":53157,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=\/wp\/v2\/posts\/53140\/revisions\/53157"}],"wp:attachment":[{"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=53140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=53140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shamusyoung.com\/twentysidedtale\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=53140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}