footnote.t | documentation |
#charset "us-ascii" /* * Copyright (c) 2000, 2006 Michael J. Roberts. All Rights Reserved. * * TADS 3 Library - footnotes * * This module defines objects related to footnotes. */ /* include the library header */ #include "adv3.h" /* ------------------------------------------------------------------------ */ /* * Footnote - this allows footnote references to be generated in * displayed text, and the user to retrieve the contents of the footnote * on demand. * * Create an instance of Footnote for each footnote. For each footnote * object, define the "desc" property as a double-quoted string (or * method) displaying the footnote's contents. * * To display a footnote reference in a passage of text, call * <<x.noteRef>>, where x is the footnote object in question. That's all * you have to do - we'll automatically assign the footnote a sequential * number (so that footnote references are always seen by the player in * ascending order, regardless of the order in which the player * encounters the sources of the footnotes), and the NOTE command will * automatically figure out which footnote object is involved for a given * footnote number. * * This class also serves as a daemon notification object to receive * per-command daemon calls. The first time we show a footnote * reference, we'll show an explanation of how footnotes work. */ class Footnote: object /* * Display the contents of the footnote - this will be called when * the user asks to show the footnote with the "NOTE n" command. * Each instance must provide suitable text here. */ desc = "" /* * Get a reference to the footnote for use in a passage of text. * This returns a single-quoted string to display as a reference to * the footnote. */ noteRef { /* * If the sensory context is blocking output, do not consider * this a reference to the footnote at all, since the player * won't see it. */ if (senseContext.isBlocking) return ''; /* * if we haven't already assigned a number to this footnote, * assign one now */ if (footnoteNum == nil) { /* * Allocate a new footnote number and remember it as our * own. Note that we want the last footnote number for all * footnotes, so use the Footnote class property * lastFootnote. */ footnoteNum = ++(Footnote.lastFootnote); /* * add myself to the class's list of numbered notes, so we * can find this footnote easily again given its number */ Footnote.numberedFootnotes.append(self); /* note that we've generated a footnote reference */ Footnote.everShownFootnote = true; } /* * If we're allowed to show footnotes, return the library * message text to display given the note number. If all * footnotes are being hidden, or if we're only showing new * footnotes and we've already read this one, return an empty * string. */ switch(footnoteSettings.showFootnotes) { case FootnotesFull: /* we're showing all footnotes unconditionally */ return gLibMessages.footnoteRef(footnoteNum); case FootnotesMedium: /* we're only showing unread footnotes */ return footnoteRead ? '' : gLibMessages.footnoteRef(footnoteNum); case FootnotesOff: /* we're hiding all footnotes unconditionally */ return ''; } /* * in case the status is invalid and we fall through, return an * empty string as a last resort */ return ''; } /* * Display a footnote given its number. If there is no such * footnote, we'll display an error message saying so. (This is a * class method, so it should be called directly on Footnote, not on * instances of Footnote.) */ showFootnote(num) { /* * if there's a footnote for this number, display it; otherwise, * display an error explaining that the footnote number is * invalid */ if (num >= 1 && num <= lastFootnote) { local fn; /* * it's a valid footnote number - get the footnote object * from our vector of footnotes, simply using the footnote * number as an index into the vector */ fn = numberedFootnotes[num]; /* show its description by calling 'desc' method */ fn.desc; /* note that this footnote text has been read */ fn.footnoteRead = true; } else { /* there is no such footnote */ gLibMessages.noSuchFootnote(num); } } /* SettingsItem tracking our current status */ footnoteSettings = footnoteSettingsItem /* * my footnote number - this is assigned the first time I'm * referenced; initially we have no number, since we don't want to * assign a number until the note is first referenced */ footnoteNum = nil /* * Flag: this footnote's full text has been displayed. This refers * to the text of the footnote itself, not the reference, so this is * only set when the "FOOTNOTE n" command is used to read this * footnote. */ footnoteRead = nil /* * Static property: the highest footnote number currently in use. * We start this at zero, because zero is never a valid footnote * number. */ lastFootnote = 0 /* * Static property: a vector of all footnotes which have had numbers * assigned. We use this to find a footnote object given its note * number. */ numberedFootnotes = static new Vector(20) /* static property: we've never shown a footnote reference before */ everShownFootnote = nil /* static property: per-command-prompt daemon entrypoint */ checkNotification() { /* * If we've ever shown a footnote, show the footnote * notification now. Note that we know we've never shown a * notification before simply because we're still running - we * remove this daemon as soon as it shows its notification. */ if (everShownFootnote) { /* show the first footnote notification */ gLibMessages.firstFootnote(); /* * We only want to show this notification once in the whole * game, so we can cancel this daemon now. Since we're the * event that's running, we can just tell the event manager * to remove the current event from receiving further * notifications. */ eventManager.removeCurrentEvent(); } } ; /* our FOOTNOTES settings item */ footnoteSettingsItem: SettingsItem /* our current status - the factory default is "medium" */ showFootnotes = FootnotesMedium /* our config file variable ID */ settingID = 'adv3.footnotes' /* show our short description */ settingDesc = (gLibMessages.shortFootnoteStatus(showFootnotes)) /* get the setting's external file string representation */ settingToText() { switch(showFootnotes) { case FootnotesMedium: return 'medium'; case FootnotesFull: return 'full'; default: return 'off'; } } settingFromText(str) { /* convert to lower-case and strip off spaces */ if (rexMatch('<space>*(<alpha>+)', str.toLower()) != nil) str = rexGroup(1)[3]; /* check the keyword */ switch (str) { case 'off': showFootnotes = FootnotesOff; break; case 'medium': showFootnotes = FootnotesMedium; break; case 'full': showFootnotes = FootnotesFull; break; } } ; /* pre-initialization - set up the footnote explanation daemon */ PreinitObject execute() { /* since we're available, register as the global footnote handler */ libGlobal.footnoteClass = Footnote; /* initialize the footnote notification daemon */ new PromptDaemon(Footnote, &checkNotification); } ;
TADS 3 Library Manual
Generated on 5/16/2013 from TADS version 3.1.3
Generated on 5/16/2013 from TADS version 3.1.3