#include #include /* * easyListing.t - a TADS 3 extension * Email: emily.boegheim@gmail.com * * This extension allows you to print simple lists (or vectors) of objects * using the message parameter substitution system. It works much like the * Inform 7 list-printing mechanism. * * To print a list with indefinite articles, use "{a/list listName}". To print * a list with definite articles, use "{the/list listName}". To print a list * with no articles, use "{list listName}". Remember to register the list with * the message parameter substitution system first, for instance * "gMessageParams(listName);". * * If you want finer-grained control over what your list looks like, you can * call "listName.showListWith(whicheverListerYouWantToUse)". * * This extension is open source software licensed under the MIT Licence: * * Copyright (c) 2013 Emily Boegheim * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * * Change history: * * 0.3 * - renamed extension * - cleaned up the documentation a bit * - added licence information * * 0.2 * - rewrote some of the code to be more respectful of the library code * * 0.1 * - initial version */ /* Info on the extension, so it will show up in the list of credits. */ easyListingModuleID: ModuleID name = 'Easy Listing' byline = 'by Emily Boegheim' htmlByline = 'by Emily Boegheim' version = '0.3' ; /* * Adding methods to show and return lists, and to use the correct grammar * when referring to a list. */ modify Collection /* A generic method for showing this list with any given Lister. */ showListWith(lister) { lister.showListAll(self, 0, nil); } /* * Wrapper methods for particular listers - plainLister (uses * indefinite pronouns), theLister (uses definite pronouns), and * noArticleLister (uses no pronouns). Instead of printing the lists, * these methods catch the output and return it. This is for message * substitution parameters, which require a text value to be returned * rather than printed. */ getAList() { return mainOutputStream.captureOutput(new function {showListWith(SimpleLister);}); } getTheList() { return mainOutputStream.captureOutput(new function {showListWith(theLister);}); } getPlainList() { return mainOutputStream.captureOutput(new function {showListWith(noArticleLister);}); } /* * Decide whether the list is plural or not. If it has more than one * object in it, or if the single object in it is plural, the list is * plural. */ isPlural() { return (length > 1 || (length == 1 && self[1].isPlural)); } /* * Methods for generating associated verbs - this is for the message * parameter substitution system. We'll just delegate to Thing. */ verbToBe() { return delegated Thing(); } verbWas { return delegated Thing(); } verbToHave { return delegated Thing(); } verbToDo = delegated Thing() verbToGo = delegated Thing() verbToCome = delegated Thing() verbToLeave = delegated Thing() verbToSee = delegated Thing() verbToSay = delegated Thing() verbMust = delegated Thing() verbCan = delegated Thing() verbCannot = delegated Thing() verbCant = delegated Thing() verbWill = delegated Thing() verbWont = delegated Thing() verbEndingS { return delegated Thing(); } verbEndingSD = delegated Thing() verbEndingSEd = delegated Thing() verbEndingSMessageBuilder_ = delegated Thing() verbEndingEs { return delegated Thing(); } verbEndingIes { return delegated Thing(); } /* * Methods to return the correct pronouns for the list; again, for the * message parameter substitution system. */ itNom { return (isPlural ? 'they' : (length == 1 ? delegated self[1] : 'it')); } itObj { return (isPlural ? 'them' : (length == 1 ? delegated self[1] : 'it')); } itPossAdj { return (isPlural ? 'their' : (length == 1 ? delegated self[1] : 'its')); } itPossNoun { return (isPlural ? 'theirs' : (length == 1 ? delegated self[1] : 'its')); } itReflexive { return (isPlural ? 'themselves' : (length == 1 ? delegated self[1] : 'itself')); } thatNom { return (isPlural ? 'those' : (length == 1 ? delegated self[1] : 'that')); } thatIsContraction { return delegated Thing(); } thatObj { return (isPlural ? 'those' : (length == 1 ? delegated self[1] : 'that')); } itIs { return delegated Thing(); } itIsContraction { return delegated Thing(); } /* * The pronoun selector. This will only get called when there is a * single item in the list and a method has been delegated to that * item. So we'll delegate this to that single item as well. */ pronounSelector = delegated self[1] /* "dummyName", for the "subj" message parameter substition trick. */ dummyName = '' ; /* Add new options for choosing which articles to use in a list. */ modify SimpleLister definiteArticle = ListerCustomFlag(1) noArticle = ListerCustomFlag(2) ; /* Modify Thing.showListItem to check which article to use. */ modify Thing showListItemGen(options, pov, infoTab, stateNameProp) { local info; local st; local stName; /* get my visual information from the point of view */ info = infoTab[self]; /* check which article to use */ local nameProp; if (options & SimpleLister.noArticle) nameProp = &name; else if (options & SimpleLister.definiteArticle) nameProp = &theName; else nameProp = &listName; /* show the item's list name */ say(withVisualSenseInfo(pov, info, nameProp)); /* * If we have a list state with a name, show it. Note that to * obtain the state name, we have to pass a list of the objects * being listed to the stateNameProp method of the state object; * we're the only object we're showing for this particular * display list element, so we simply pass a single-element list * containing 'self'. */ if ((st = getStateWithInfo(info, pov)) != nil && (stName = st.(stateNameProp)([self])) != nil) { /* we have a state with a name - show it */ gLibMessages.showListState(stName); } } ; /* The theLister prints a simple list with definite articles. */ theLister: SimpleLister showList(pov, parent, lst, options, indent, infoTab, parentGroup) { options = options | definiteArticle; inherited(pov, parent, lst, options, indent, infoTab, parentGroup); } ; /* The noArticleLister prints a simple list with no articles. */ noArticleLister: SimpleLister showList(pov, parent, lst, options, indent, infoTab, parentGroup) { options = options | noArticle; inherited(pov, parent, lst, options, indent, infoTab, parentGroup); } ; /* Add the new message parameters to the message builder. */ modify langMessageBuilder paramList_ = static inherited() + [ ['list', &getPlainList, nil, nil, nil], ['the/list', &getTheList, nil, nil, nil], ['a/list', &getAList, nil, nil, nil] ] ;