def speechReview_getCharacterDescription(locale, character): """ This function is derived from the default getCharacterDescription function specifically to handle the speechreview mode behavior. @param locale: the locale (language[_COUNTRY]) the description should be for. @type locale: string @param character: the character who's description should be retrieved. @type character: string @return: the found description for the given character. if speech/Braille review mode is turned on, one description is returned at a time. @rtype: string """ try: l = characterProcessing._charDescLocaleDataMap.fetchLocaleData(locale) except LookupError: if not locale.startswith('en'): return characterProcessing.getCharacterDescription('en', character) raise LookupError("en") desc = l.getCharacterDescription(character) if not desc and not locale.startswith('en'): desc = characterProcessing.getCharacterDescription('en', character) if CJK["speechReview"] == "Off": #Perform default behavior. return desc if not desc: #There is no description for the character, so return nothing to allow the character to be passed to the processSymbol function. #Allows for speaking of punctuation and symbols absent from the dictionary. return None #Append the decimal and hexadecimal representation of the character to the description. c = ord(character) s = "%d," % c + " - ".join(hex(c)) desc.append(s) currentDesc = "" if CJK["direction"] != 0 and CJK["previousCharacter"] == character: #Determine the list position for the next character description and handle looping between beginning and end of the list. CJK["descIndex"] = CJK["descIndex"] + CJK["direction"] if abs(CJK["descIndex"]) == len(desc): CJK["descIndex"] = 0 else: #The caret or review cursor has moved, so reset the index and store the character for future comparison. CJK["previousCharacter"] = character CJK["descIndex"] = 0 if not isAlphanumeric(character): #Allow speaking the character alone followed by a pause before the first description. #This could be desirable when the user wants to quickly move through a sentence without hearing extra information. currentDesc = character currentDesc = currentDesc + " " + desc[CJK["descIndex"]] #Free the character descriptions from the decimal and hexadecimal representation at the end of the list. #This restores default behavior of the characterProcessing.getCharacterDescription function. desc.remove(s) return currentDesc.strip()
def getFormattedCandidateName(self, number, candidate): if config.conf["inputComposition"][ "alwaysIncludeShortCharacterDescriptionInCandidateName"]: describedSymbols = [] for symbol in candidate: try: symbolDescriptions = characterProcessing.getCharacterDescription( speech.getCurrentLanguage(), symbol) or [] except TypeError: symbolDescriptions = [] if len(symbolDescriptions) >= 1: description = symbolDescriptions[0] if description.startswith('(') and description.endswith( ')'): describedSymbols.append(description[1:-1]) else: # Translators: a message announcing a candidate's character and description. describedSymbols.append( _(u"{symbol} as in {description}").format( symbol=symbol, description=description)) else: describedSymbols.append(symbol) candidate = u", ".join(describedSymbols) # Translators: a formatted message announcing a candidate's number and candidate text. return _(u"{number} {candidate}").format(number=number, candidate=candidate)
def custom_reportNewText(self, oldString, newString): if (config.conf["keyboard"]["speakTypedCharacters"] or config.conf["keyboard"]["speakTypedWords"]): newText = calculateInsertedChars(oldString.strip(u'\u3000'), newString.strip(u'\u3000')) newSpeechText = None newBrailleText = None if CJK["speechReview"] == "On" and not isAlphanumeric(newText) and len( newText) == 1: try: newSpeechText = speechReview_getCharacterDescription( CJK["locale"], newText) except TypeError: pass if (CJK["brailleReview"] == "On" or CJK["brailleReview"] == "Auto" ) and not isAlphanumeric(newText) and len(newText) == 1: try: newBrailleText = newText + " " + " ".join( characterProcessing.getCharacterDescription( CJK["locale"], newText)) except TypeError: pass if newSpeechText: queueHandler.queueFunction(queueHandler.eventQueue, ui.reviewMessage, newSpeechText) elif newText: queueHandler.queueFunction( queueHandler.eventQueue, speech.speakText, newText, symbolLevel=characterProcessing.SYMLVL_ALL)
def _speakSpellingGen(text,locale,useCharacterDescriptions): textLength=len(text) synth=getSynth() synthConfig=config.conf["speech"][synth.name] for count,char in enumerate(text): uppercase=char.isupper() charDesc=None if useCharacterDescriptions: from characterProcessing import getCharacterDescription charDesc=getCharacterDescription(locale,char.lower()) if charDesc: char=charDesc else: char=processSymbol(char) if uppercase and synthConfig["sayCapForCapitals"]: char=_("cap %s")%char if uppercase and synth.isSupported("pitch") and synthConfig["raisePitchForCapitals"]: oldPitch=synthConfig["pitch"] synth.pitch=max(0,min(oldPitch+synthConfig["capPitchChange"],100)) index=count+1 log.io("Speaking character %r"%char) if len(char) == 1 and synthConfig["useSpellingFunctionality"]: synth.speakCharacter(char,index=index) else: synth.speakText(char,index=index) if uppercase and synth.isSupported("pitch") and synthConfig["raisePitchForCapitals"]: synth.pitch=oldPitch while textLength>1 and (isPaused or getLastSpeechIndex()!=index): yield yield if uppercase and synthConfig["beepForCapitals"]: tones.beep(2000,50)
def speakDescription(text, fields): curLanguage = speech.getCurrentLanguage() if not config.conf['speech'][ 'autoLanguageSwitching'] and characterProcessing.getCharacterDescription( curLanguage, text.lower()): return speakSpelling(text, curLanguage, useCharacterDescriptions=True) for field in fields: if isinstance(field, six.string_types ) and characterProcessing.getCharacterDescription( curLanguage, field.lower()): speakSpelling(field, curLanguage, useCharacterDescriptions=True) elif isinstance( field, textInfos.FieldCommand) and field.command == "formatChange": curLanguage = field.field.get('language', curLanguage) or curLanguage
def getLongDesc(s): try: lang = languageHandler.getLanguage()[:2] if len(s) == 1 and ord(s) < 128 and lang != 'ja': d = characterProcessing.getCharacterDescription(lang, s) log.debug(repr([s, d, 0])) if d: r = ' '.join(d) return r d = characterProcessing.getCharacterDescription('ja', s) log.debug(repr([s, d, 1])) if d: r = ' '.join(d) return r except Exception as e: log.debug(repr(e)) log.debug(repr([s, 2])) return s
def getFormattedCandidateDescription(self,candidate): descriptions=[] numSymbols=len(candidate) if candidate else 0 if numSymbols!=1: return u"" symbol=candidate[0] try: symbolDescriptions=characterProcessing.getCharacterDescription(speech.getCurrentLanguage(),symbol) or [] except TypeError: symbolDescriptions=[] if config.conf["inputComposition"]["alwaysIncludeShortCharacterDescriptionInCandidateName"]: symbolDescriptions=symbolDescriptions[1:] if len(symbolDescriptions)<1: return u"" return u", ".join(symbolDescriptions)
def script_modified_review_nextCharacter(self, gesture): #Add character description Braille output to the review character when Braille review mode is turned on. lineInfo = api.getReviewPosition().copy() lineInfo.expand(textInfos.UNIT_LINE) charInfo = api.getReviewPosition().copy() charInfo.expand(textInfos.UNIT_CHARACTER) charInfo.collapse() res = charInfo.move(textInfos.UNIT_CHARACTER, 1) if res == 0 or charInfo.compareEndPoints(lineInfo, "endToEnd") >= 0: ui.reviewMessage(_("Right")) reviewInfo = api.getReviewPosition().copy() reviewInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(reviewInfo, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) char = reviewInfo.text.lower() if not isAlphanumeric(char) and CJK["brailleReview"] == "Auto": try: charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass else: api.setReviewPosition(charInfo) charInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(charInfo, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) char = charInfo.text.lower() if not isAlphanumeric(char) and CJK["brailleReview"] == "Auto": try: charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass
def script_forward_review_currentCharacter(self, gesture): #When speech review mode is enabled, the first character description is spoken on first script call. #When Braille review mode is set to "On" or "Auto", character descriptions are displayed on the first script call. CJK["direction"] = 1 info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) count = getLastScriptRepeatCount() try: c = ord(info.text) except: c = 0 if count == 1 or (CJK["speechReview"] == "On" or CJK["brailleReview"] != "Off"): CJK["isReviewCharacter"] = True if count == 1 or CJK["speechReview"] == "On": speech.speakSpelling(info.text, useCharacterDescriptions=True) else: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) if CJK["brailleReview"] == "On" or CJK["brailleReview"] == "Auto": try: char = info.text.lower() charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass elif count == 0: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) else: try: speech.speakMessage("%d," % c) speech.speakSpelling(hex(c)) except: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) #Reset parameters to prepare for the next call. CJK["direction"] = 0 CJK["isReviewCharacter"] = False
def getFormattedCandidateName(self,number,candidate): if config.conf["inputComposition"]["alwaysIncludeShortCharacterDescriptionInCandidateName"]: describedSymbols=[] for symbol in candidate: try: symbolDescriptions=characterProcessing.getCharacterDescription(speech.getCurrentLanguage(),symbol) or [] except TypeError: symbolDescriptions=[] if len(symbolDescriptions)>=1: description=symbolDescriptions[0] if description.startswith('(') and description.endswith(')'): describedSymbols.append(description[1:-1]) else: # Translators: a message announcing a candidate's character and description. describedSymbols.append(_(u"{symbol} as in {description}").format(symbol=symbol,description=description)) else: describedSymbols.append(symbol) candidate=u", ".join(describedSymbols) # Translators: a formatted message announcing a candidate's number and candidate text. return _(u"{number} {candidate}").format(number=number,candidate=candidate)
def getFormattedCandidateName(self, number, candidate): #nvdajp begin import jpUtils if config.conf["keyboard"]["nvdajpEnableKeyEvents"]: fb = (braille.handler.displaySize > 0) c = jpUtils.getDiscriminantReading(candidate, forBraille=fb) log.debug(u"{number} {candidate} {c}".format(number=number, candidate=candidate, c=c)) if config.conf["language"]["announceCandidateNumber"]: return _(u"{number} {candidate}").format(number=number, candidate=c) return c #nvdajp end if config.conf["inputComposition"][ "alwaysIncludeShortCharacterDescriptionInCandidateName"]: describedSymbols = [] for symbol in candidate: try: symbolDescriptions = characterProcessing.getCharacterDescription( speech.getCurrentLanguage(), symbol) or [] except TypeError: symbolDescriptions = [] if len(symbolDescriptions) >= 1: description = symbolDescriptions[0] if description.startswith('(') and description.endswith( ')'): describedSymbols.append(description[1:-1]) else: # Translators: a message announcing a candidate's character and description. describedSymbols.append( _(u"{symbol} as in {description}").format( symbol=symbol, description=description)) else: describedSymbols.append(symbol) candidate = u", ".join(describedSymbols) # Translators: a formatted message announcing a candidate's number and candidate text. return _(u"{number} {candidate}").format(number=number, candidate=candidate)
def custom_doCursorMove(self, region): """ This is derived from BrailleHandler._doCursorMove to handle the Braille review behavior. When the cursor is moved to a new raw text region, the region is displayed in Braille. Once the cursor is moved with left and right arrow, the character descriptions are displayed for each character at the cursor position. @param self: the instance of BrailleHandler currently initialized @type self: braille.BrailleHandler @param region: the region of Braille displayed @type region: braille.Region """ self.mainBuffer.saveWindow() region.update() self.mainBuffer.update() self.mainBuffer.restoreWindow() if region.brailleCursorPos is not None: self.mainBuffer.scrollTo(region, region.brailleCursorPos) if self.buffer is self.mainBuffer: self.update() elif self.buffer is self.messageBuffer and keyboardHandler.keyCounter > self._keyCountForLastMessage: self._dismissMessage() if CJK["brailleReview"] == "Auto" and CJK[ "previousRawText"] == region.rawText and CJK[ "previousCursorPos"] != region.cursorPos: #The cursor is inside the raw text of the previous region and its position as moved, so display the character descriptions. try: i = region.cursorPos char = region.rawText[int(_(i or 0))] charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char.lower()) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: BrailleHandler.message(handler, char) else: #This region has a new raw text, so store the raw text for subsequent comparison. CJK["previousRawText"] = region.rawText CJK["previousCursorPos"] = region.cursorPos
def custom_getSpellingSpeech( # noqa: C901 text: str, locale: Optional[str] = None, useCharacterDescriptions: bool = False): defaultLanguage = getCurrentLanguage() if not locale or (not config.conf['speech']['autoDialectSwitching'] and locale.split('_')[0] == defaultLanguage.split('_')[0]): locale = defaultLanguage if not text: # Translators: This is spoken when NVDA moves to an empty line. yield _("blank") return if not text.isspace(): text = text.rstrip() synth = synthDriverHandler.getSynth() synthConfig = config.conf["speech"][synth.name] charMode = False textLength = len(text) count = 0 localeHasConjuncts = True if locale.split( '_', 1)[0] in LANGS_WITH_CONJUNCT_CHARS else False charDescList = getCharDescListFromText( text, locale) if localeHasConjuncts else text for item in charDescList: if localeHasConjuncts: # item is a tuple containing character and its description speakCharAs = item[0] charDesc = item[1] else: charDesc = None # item is just a character. speakCharAs = item if CJK["speechReview"] == "Off" and useCharacterDescriptions: charDesc = characterProcessing.getCharacterDescription( locale, speakCharAs.lower()) else: #do not speak character descriptions for alphanumeric characters unless the function is called by the review_currentCharacter method. #This is to prevent phonetic spelling of the alphabets when typing, and moving the caret and review cursor. if isAlphanumeric( speakCharAs) and not CJK["isReviewCharacter"]: #The cursor has moved, so reset the previously stored character. #This allows for a more consistent speech feedback by always speaking the phonetic spelling of alphanumeric characters first after the focus moves. CJK["previousCharacter"] = "" elif CJK["speechReview"] == "On": #Retrieve the character description one at a time. charDesc = speechReview_getCharacterDescription( locale, speakCharAs.lower()) if charDesc and CJK["speechReview"] == "On": speakCharAs = "".join(charDesc) elif charDesc: IDEOGRAPHIC_COMMA = u"\u3001" speakCharAs = charDesc[ 0] if textLength > 1 else IDEOGRAPHIC_COMMA.join(charDesc) else: speakCharAs = characterProcessing.processSpeechSymbol( locale, speakCharAs) uppercase = speakCharAs.isupper() # if useCharacterDescriptions and charDesc: # IDEOGRAPHIC_COMMA = u"\u3001" # speakCharAs=charDesc[0] if textLength>1 else IDEOGRAPHIC_COMMA.join(charDesc) # else: # speakCharAs=characterProcessing.processSpeechSymbol(locale,speakCharAs)''' if uppercase and synthConfig["sayCapForCapitals"]: # Translators: cap will be spoken before the given letter when it is capitalized. speakCharAs = _("cap %s") % speakCharAs if uppercase and synth.isSupported( "pitch") and synthConfig["capPitchChange"]: yield PitchCommand(offset=synthConfig["capPitchChange"]) if config.conf['speech']['autoLanguageSwitching']: yield LangChangeCommand(locale) if len(speakCharAs) == 1 and synthConfig["useSpellingFunctionality"]: if not charMode: yield CharacterModeCommand(True) charMode = True elif charMode: yield CharacterModeCommand(False) charMode = False if uppercase and synthConfig["beepForCapitals"]: yield BeepCommand(2000, 50) yield speakCharAs if uppercase and synth.isSupported( "pitch") and synthConfig["capPitchChange"]: yield PitchCommand() yield EndUtteranceCommand()