-- CONVERT CASE BROKER -- -- Movie Script -- -- © January 2005, James Newton -- ---------------------------------------------------------------------- -- 050525 JN: * UpperCase() and LowerCase() changed to CaseUpper() and -- CaseLower() -- * CaseSentence() and exception management added. ---------------------------------------------------------------------- -- This Movie Script can be used to convert strings to lowercase or -- UPPERCASE. Accented characters are treated correctly on both -- platforms. Non-alphabetical characters are ignored. -- -- NOTE: This Broker script will not work if: -- * Its name is different from "Convert Case Broker" -- * Its scriptType is not #movie -- * There is a member named "Convert Case Broker" in a lower-numbered -- cast slot -- * There is a Movie Script member with the handlers CaseLower(), -- CaseUpper() or GetConvertCaseBroker() in a lower-numbered cast -- slot. -- -- put CaseUpper("Räksmörgås") -- -- "RÄKSMÖRGÅS" -- -- put CaseLower("RÄKSMÖRGÅS") -- -- "räksmörgås" -- -- put CaseSentence("RÄKSMÖRGÅS") -- -- "Räksmörgås" ---------------------------------------------------------------------- -- PUBLIC METHODS -- on CaseLower(aString) ------------------------------------------------ -- INPUT: should be a string -- OUTPUT: Returns converted to lowercase -------------------------------------------------------------------- tBroker = GetConvertCaseBroker() return tBroker.mLowerCase(aString) end CaseLower on CaseUpper(aString) ------------------------------------------------ -- INPUT: should be a string -- OUTPUT: Returns converted to UPPERCASE -------------------------------------------------------------------- tBroker = GetConvertCaseBroker() return tBroker.mUpperCase(aString) end CaseUpper on CaseSentence(aString) --------------------------------------------- -- INPUT: should be a string -- OUTPUT: Returns converted to lower, except for the -- first character following a full stop which is itself -- followed by a word delimiter (RETURN, SPACE, ...), and -- words which appear in anExceptionList -------------------------------------------------------------------- tBroker = GetConvertCaseBroker() return tBroker.mSentenceCase(aString) end CaseSentence on CaseGetExceptions() ----------------------------------------------- -- OUTPUT: Returns a linear list of exception strings for -- CaseSentence(). You can use... -- -- SetPref("Case", string(CaseGetExceptions())) -- -- ... to save the current list of exceptions for reuse in -- the next session. -------------------------------------------------------------------- tBroker = GetConvertCaseBroker() return tBroker.mGetCaseExceptions() end CaseGetExceptions on CaseLoadExceptions(aStringOrList) --------------------------------- -- ACTION: Uses value(GetPref(aStringOrList)) or the raw list value -- to load a list of exceptions. -------------------------------------------------------------------- tBroker = GetConvertCaseBroker() return tBroker.mLoadCaseExceptions(aStringOrList) end CaseLoadExceptions -- SCRIPT PROPERTY AND METHOD -- property broker -- instance of this script on GetConvertCaseBroker() --------------------------------------------- -- ACTION: Ensures that this script possesses a .broker property -- whose value is an instance of itself -- OUTPUT: Returns this script's .broker instance -------------------------------------------------------------------- tScript = script("Convert Case Broker") -- HARD-CODED script name tBroker = tScript.broker if not objectP(tBroker) then tBroker = tScript.new() -- implicit method tBroker.mInitialize() tScript.broker = tBroker end if return tBroker end GetConvertCaseBroker -- PRIVATE PROPERTIES AND METHODS -- property pUPPERCASEAccents -- ["Á", "À", ..., "Œ", "Ÿ"] property pLowercaseAccents -- ["á", "à", ..., "œ", "ÿ"] property pExceptionList -- ["Proper Nouns", "AndCamelHump", -- "Phrases For SentenceCase()" on mInitialize(me) --------------------------------------------------- -- SENT BY GetConvertCaseBroker() -- ACTION: Creates a list for storing the latest index value for -- each seed name. Prepares equivalence lists so that -- all strings can be converted to uppercase for case- -- sensitive list comparisons. -------------------------------------------------------------------- -- On Windows, in versions of Director prior to 8.5, "Â" works -- as a continuation character, just like "¬". The lists below must -- avoid using this character as such. pUPPERCASEAccents = ["Á", "À", 0, "Ä", "Ã", "Å", "Ç", "É", "È", "Ê", "Ë", "Í", "Ì", "Î", "Ï", "Ñ", "Ó", "Ò", "Ô", "Ö", "Õ", "Ú", "Ù", "Û", "Ü", "Æ", "Ø", "Œ", "Ÿ", "ß"] if the platform contains "Macintosh" then pUPPERCASEAccents[3] = numToChar(229) else pUPPERCASEAccents[3] = numToChar(194) end if pLowercaseAccents = ["á", "à", "â", "ä", "ã", "å", "ç", "é", "è", "ê", "ë", "í", "ì", "î", "ï", "ñ", "ó", "ò", "ô", "ö", "õ", "ú", "ù", "û", "ü", "æ", "ø", "œ", "ÿ", "ß"] pExceptionList = [] pExceptionList.sort() end mInitialize on mLowerCase(me, aString) ------------------------------------------- -- INPUT: is a string -- OUTPUT: Returns converted to lowercase -------------------------------------------------------------------- tLength = the number of chars of aString repeat with i = 1 to tLength tChar = char i of aString tCharNum = charToNum(tChar) tAccent = pUPPERCASEAccents.getPos(tChar) if tAccent then put pLowercaseAccents[tAccent] into char i of aString else if tCharNum > 64 and tCharNum < 91 then put numToChar(tCharNum + 32) into char i of aString end if end repeat return aString end mLowerCase on mUpperCase(me, aString) ------------------------------------------- -- INPUT: is a string -- OUTPUT: Returns converted to UPPERCASE -------------------------------------------------------------------- tLength = the number of chars of aString repeat with i = 1 to tLength tChar = char i of aString tCharNum = charToNum(tChar) tAccent = pLowercaseAccents.getPos(tChar) if tAccent then put pUPPERCASEAccents[tAccent] into char i of aString else if tCharNum > 96 and tCharNum < 123 then put numToChar(tCharNum - 32) into char i of aString end if end repeat return aString end mUpperCase on mSentenceCase( me, aString) --------------------------------------- -- INPUT: should be a string -- may be a linear list of words containing -- UpperCase letters, such as ["OpenSpark", "Director", MX"] -- OUTPUT: Returns converted to lower, except for the -- first character following a full stop which is itself -- followed by a word delimiter (RETURN, SPACE, ...), and -- words which appear in anExceptionList. -- NOTE: This handler does not take into account the use of -- parentheses which completely encloses a sentence: -- "(initial capital ignored.) following capital ignored" -------------------------------------------------------------------- aString = me.mLowerCase(aString) vNewSentence = TRUE vWordCount = the number of words in aString repeat with i = 1 to vWordCount vWord = word i of aString if vNewSentence then vCapital = me.mUpperCase(char 1 of vWord) put vCapital into char 1 of word i of aString end if case the last char of vWord of ".", "!", "?": vNewSentence = TRUE otherwise vNewSentence = FALSE end case end repeat -- Check for exceptions i = pExceptionList.count() repeat while i vException = pExceptionList[i] aString = ReplaceAll(aString, vException, vException) i = i - 1 end repeat return aString end mSentenceCase on mGetCaseExceptions(me) -------------------------------------------- -- OUTPUT: Returns a linear list of exception strings for -- CaseSentence(). You can use... -- -- SetPref("Case", string(CaseGetExceptions())) -- -- ... to save the current list of exceptions for reuse in -- the next session. -------------------------------------------------------------------- return pExceptionList.duplicate() end mGetCaseExceptions on mLoadCaseExceptions(me, aStringOrList, aReplace) ------------------ -- ACTION: Uses value(GetPref(aStringOrList)) or the raw list value -- to load a list of exceptions. -------------------------------------------------------------------- if stringP(aStringOrList) then vTemp = GetPref(aStringOrList) if stringP(vTemp) then aStringOrList = value(vTemp) else vMessage = "No pref file named ""E&aStringOrList"E&"." return xCeption(#case, vMessage) end if end if if ilk(aStringOrList) <> #list then vMessage = "Invalid list: "&aStringOrList return xCeption(#case, vMessage) end if case aReplace of TRUE, #replace: -- Replace current pExceptionList pExceptionList = aStringOrLIst otherwise: -- Add new items to pExceptionList i = aStringOrList.count() repeat while i vException = aStringOrList[i] if stringP(vException) then if not pExceptionList.getPos(vException) then pExceptionList.add(vException) end if end if i = i - 1 end repeat end case return 0 -- no error end mLoadCaseExceptions -- UTILITY -- on ReplaceAll(aString, aSubString, aReplacement) --------------------- -- INPUT: is the main string to search in -- is a string which may appear in -- is a string which is to replace all -- occurrences of in -- OUTPUT: returns an updated version of where all -- occurrences of have been replaced by -- -------------------------------------------------------------------- if aSubString = "" then return aString end if tTreatedString = "" tLengthAdjust = the number of chars of aSubString - 1 repeat while TRUE tOffset = offset(aSubString, aString) if tOffset then -- There is at least one more occurrence... if tOffset - 1 then -- ... but there is intervening text to copy first put chars(aString, 1, (tOffset - 1)) after tTreatedString end if put aReplacement after tTreatedString delete char 1 to (tOffset + tLengthAdjust) of aString else -- There are no more occurrences. Add the remaining text -- after the last replaced occurrence. put aString after tTreatedString return tTreatedString end if end repeat end ReplaceAll