def getVocabularySection(self, inputString): # we only need 4 entries, but because of double entries we might end up # with some being merged, also need +1 to show the "more entries" # play safe and select 10 # TODO true contains dictResult = self._dictionary.getForHeadword( '*' + inputString + '*', orderBy=['Weight'], limit=10) htmlList = [] if dictResult: htmlList.append('<table class="vocabulary">') # don't display alternative if the charString is found # in the given string showAlternative = lambda charString, _: \ (charString.find(inputString) < 0) htmlList.append(self._getVocabularyTable(dictResult[:4], useAltFunc=showAlternative)) htmlList.append('</table>') if len(dictResult) > 4: htmlList.append( '<a class="meta" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64('vocabulary' \ + ':' + inputString), gettext('All entries...'))) else: htmlList.append('<span class="meta">%s</span>' \ % gettext('No entries found')) return '\n'.join(htmlList)
def getOtherVocabularySearchSection(self, inputString): """ Gets a list of vocabulary entries containing the given inputString. """ htmlList = [] # TODO use caching dictResult = self._dictionary.getFor('*' + inputString + '*', orderBy=['Weight']) if dictResult: htmlList.append('<table class="otherVocabulary">') htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Other matches')) augmentedInput = '*' + inputString + '*' htmlList.append(self._getVocabularyTable(dictResult, useAltFunc=lambda x, y: \ self._matchesInput(inputString, y) \ and not self._matchesInput(inputString, x))) htmlList.append('</table>') else: htmlList.append('<span class="meta">%s</span>' \ % gettext('No matches found')) return '\n'.join(htmlList)
def getCharacterWithSamePronunciationSection(self, inputString): """Gets a list of characters with the same pronunciation.""" dictResult = self._searchDictionarySamePronunciationAs(inputString) # group by reading and character charDict = {} for char, charAlt, reading, translation in dictResult: if reading not in charDict: charDict[reading] = {} if char not in charDict[reading]: charDict[reading][char] = [] charDict[reading][char].append( (char, charAlt, reading, translation)) if charDict: html = '' for reading in sorted(charDict.keys(), reverse=True): characterLinks = [] for char in charDict[reading]: characterLinks.append('<li><span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>%s</li>' % self._getDictionaryInfo(char, charDict[reading][char])) html += '<h3>%s</h3>' % reading \ + '<ul>%s</ul>' % ' '.join(characterLinks) return '<div class="samereading">' + html + '</div>' else: return '<span class="meta">%s</span>' % gettext('No entries found')
def getEduTwLink(self, charString): if len(charString) == 1: relLink = self._dictionary.charDB.getCharacterIndex(charString, 'EduTwIndex') if relLink: link = u'http://www.edu.tw/files/site_content/M0001/bishuen/' \ + relLink return link, (u'常用國字標準字體筆順手冊 (%s)' % gettext('edu.tw stroke order handbook'))
def getStrokeOrderSection(self, inputString): strokeOrderFunc, _ \ = self.STROKE_ORDER_SOURCES[self.BIG_STROKE_ORDER_TYPE] strokeOrder = strokeOrderFunc(self, inputString) if strokeOrder: return '<span class="bigstrokeorder">%s</span>' % strokeOrder else: return '<span class="meta">%s</span>' % gettext('no information')
def getFullVocabularySection(self, inputString): """ Gets a list of dictionary entries with exact matches and matches including the given character string. """ dictResult = self._dictionary.getForHeadword(inputString) htmlList = [] htmlList.append('<table class="fullVocabulary">') # exact matches htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Dictionary entries')) if dictResult: showAlternative = lambda charString, _: (charString != inputString) htmlList.append(self._getVocabularyTable(dictResult, useAltFunc=showAlternative)) else: htmlList.append( '<tr><td colspan="3"><span class="meta">%s</span></td></tr>' \ % gettext('No exact matches found')) # other matches # TODO true contains dictResult = self._dictionary.getForHeadword('*' + inputString + '*', orderBy=['Reading']) if dictResult: htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Other matches')) # don't display alternative if the charString is found in the # given string showAlternative = lambda charString, _: \ (charString.find(inputString) < 0) htmlList.append(self._getVocabularyTable(dictResult, useAltFunc=showAlternative)) htmlList.append('</table>') return '\n'.join(htmlList)
def getSimilarVocabularySearchSection(self, inputString): """ Gets a list of vocabulary entries with pronunciation similar to the given string. """ htmlList = [] dictResult = self._dictionary.getForSimilarReading(inputString, orderBy=['Reading']) if dictResult: htmlList.append('<table class="similarVocabulary">') htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Similar pronunciations')) htmlList.append(self._getVocabularyTable(dictResult)) htmlList.append('</table>') else: htmlList.append('<span class="meta">%s</span>' \ % gettext('No matches found')) return '\n'.join(htmlList)
def getDecompositionTreeSection(self, inputString): """Gets a tree of components included in the given character.""" def getLayer(decompTree, isSubTree=False): if type(decompTree) != type(()): char = decompTree if char != u'?': if char in seenEntry: return '<span class="entry">' \ + '<span class="character">%s</span>' % char \ + '</span>' else: seenEntry.add(char) return '<span class="entry"><span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>%s</span>' % self._getDictionaryInfo(char) else: return '<span class="entry meta">%s</span>' \ % gettext('unknown') else: layout, char, tree = decompTree if char: if isSubTree: head = layout + '<span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>' \ + self._getDictionaryInfo(char) else: # don't show dictionary information for the root element head = layout \ + '<span class="character">%s</span>' % char else: head = layout subLayer = [] for idx, entry in enumerate(tree): cssClass = 'decomposition' if idx == len(tree) - 1: cssClass += ' last' subLayer.append('<li class="%s">%s</li>' \ % (cssClass, getLayer(entry, isSubTree=True))) return '<span class="entry">%s<ul>%s</ul></span>' \ % (head, ''.join(subLayer)) decompTree = self._dictionary.charDB.getCharacterDecomposition(inputString) if decompTree: seenEntry = set() return '<div class="tree">%s</div>' % getLayer(decompTree) else: return '<span class="meta">%s</span>' % gettext('No entry found')
def getComponentSearchResult(self, components, includeEquivalentRadicalForms=False, includeSimilarCharacters=False): """Gets a list of characters containing the given components.""" chars = self.charDB.getCharactersForComponents(components, includeEquivalentRadicalForms=includeEquivalentRadicalForms, includeSimilarCharacters=includeSimilarCharacters) if chars: charLinks = [] for char in chars: charLinks.append( '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char)) html = '<span class="character">%s</span>' % ' '.join(charLinks) else: html = '<p class="meta">%s</p>' % gettext('No entries') return html, len(chars)
def getLayer(decompTree, isSubTree=False): if type(decompTree) != type(()): char = decompTree if char != u'?': if char in seenEntry: return '<span class="entry">' \ + '<span class="character">%s</span>' % char \ + '</span>' else: seenEntry.add(char) return '<span class="entry"><span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>%s</span>' % self._getDictionaryInfo(char) else: return '<span class="entry meta">%s</span>' \ % gettext('unknown') else: layout, char, tree = decompTree if char: if isSubTree: head = layout + '<span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>' \ + self._getDictionaryInfo(char) else: # don't show dictionary information for the root element head = layout \ + '<span class="character">%s</span>' % char else: head = layout subLayer = [] for idx, entry in enumerate(tree): cssClass = 'decomposition' if idx == len(tree) - 1: cssClass += ' last' subLayer.append('<li class="%s">%s</li>' \ % (cssClass, getLayer(entry, isSubTree=True))) return '<span class="entry">%s<ul>%s</ul></span>' \ % (head, ''.join(subLayer))
def getCharacterWithComponentSection(self, inputString): """Gets a list of characters with the given character as component.""" chars = self._dictionary.charDB.getCharactersForComponents([inputString]) if inputString in chars: chars.remove(inputString) if chars: characterLinks = [] for char in chars: #characterLinks.append( #'<a class="character" href="#lookup(%s)">%s</a>' \ #% (util.encodeBase64(char), char)) characterLinks.append('<li><span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>%s</li>' % self._getDictionaryInfo(char)) return '<div class="components"><ul>%s</ul></div>' \ % ' '.join(characterLinks) else: return '<span class="meta">%s</span>' % gettext('No entries found')
def _getContainedEntitiesSection(self, inputString, dictResult): """ Gets a list of dictionary entries for single characters of the given character string. """ def sortDictionaryResults(x, y): charStringA, charStringAltA, _, _ = x charStringB, charStringAltB, _, _ = y a = inputString.find(charStringA) if a < 0: a = inputString.find(charStringAltA) b = inputString.find(charStringB) if b < 0: b = inputString.find(charStringAltB) if a == b: return len(charStringA) - len(charStringB) else: return a - b htmlList = [] if dictResult: dictResult.sort(sortDictionaryResults) htmlList.append('<table class="containedVocabulary">') # don't display alternative if the charString is found # in the given string showAlternative = lambda charString, _: \ (inputString.find(charString) < 0) htmlList.append(self._getVocabularyTable(dictResult, useAltFunc=showAlternative, smallSpacing=True)) htmlList.append('</table>') else: htmlList.append('<span class="meta">%s</span>' \ % gettext('No entries found')) return '\n'.join(htmlList)
def getCantoDictLink(self, charString): link = u'http://www.cantonese.sheik.co.uk/dictionary/search/' \ + '?searchtype=1&text=%s' % charString return link, gettext('CantoDict Cantonese-Mandarin-English dictionary')
def getUnihanLink(self, charString): if len(charString) == 1: link = u'http://www.unicode.org/cgi-bin/GetUnihanData.pl?' \ + u'codepoint=%s' % hex(ord(charString)).replace('0x', '') return link, gettext('Unicode Unihan database')
def getWWWJDICLink(self, charString): link = u'http://www.csse.monash.edu.au/~jwb/cgi-bin/' \ + u'wwwjdic.cgi?1MUJ%s' % charString return link, gettext('WWWJDIC Japanese-English dictionary')
def getCEDICTLink(self, charString): link = u'http://us.mdbg.net/chindict/chindict.php?wdqchs=%s' \ % charString return link, gettext('MDBG Chinese-English dictionary')
def getAudio(filePath): return (' <a class="audio" href="#play(%s)">%s</a>' % (urllib.quote(filePath.encode('utf8')), gettext('Listen')))
def getHanDeDictLink(self, charString): link = u'http://www.chinaboard.de/chinesisch_deutsch.php?' \ + u"sourceid=konqueror-search&skeys=%s" % charString return link, gettext('HanDeDict Chinese-German dictionary')
def getVocabularySearchSection(self, inputString): """ Gets the search results for the given string including exact maches and a shortened list of similar results and results including the given string. """ htmlList = [] htmlList.append('<table class="search">') # exact hits exactDictResult = self._dictionary.getFor(inputString, orderBy=['Weight']) if exactDictResult: htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Matches')) # match against input string with regular expression htmlList.append(self._getVocabularyTable(exactDictResult, useAltFunc=lambda x, y: \ self._matchesInput(inputString, y) \ and not self._matchesInput(inputString, x))) # similar pronunciation similarDictResult = self._dictionary.getForSimilarReading( inputString, orderBy=['Weight'], limit=5) if similarDictResult: htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Similar pronunciations')) htmlList.append(self._getVocabularyTable(similarDictResult[:4])) if len(similarDictResult) > 4: htmlList.append('<tr><td colspan="3">' \ + '<a class="meta" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64('similar' + ':' \ + inputString), gettext('All entries...')) + '</td></tr>') # other matches # TODO optimize and include other matches in exact run, after all # translation will be all searched with LIKE '% ... %' otherDictResult = self._dictionary.getFor('*' + inputString + '*', orderBy=['Weight']) if otherDictResult: htmlList.append('<tr><td colspan="3"><h3>%s</h3></td></tr>' \ % gettext('Other matches')) augmentedInput = '*' + inputString + '*' htmlList.append(self._getVocabularyTable(otherDictResult[:4], useAltFunc=lambda x, y: \ self._matchesInput(inputString, y) \ and not self._matchesInput(inputString, x))) if len(otherDictResult) > 4: htmlList.append('<tr><td colspan="3">' \ + '<a class="meta" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64('othervocabulary' + ':' \ + inputString), gettext('All entries...')) + '</td></tr>') # handle 0 result cases if not exactDictResult: if not similarDictResult and not otherDictResult: htmlList.append('<tr><td colspan="3">'\ + '<span class="meta">%s</span>' \ % gettext('No matches found') \ + '</td></tr>') else: htmlList.insert(0, '<tr><td colspan="3">'\ + '<span class="meta">%s</span>' \ % gettext('No exact matches found') \ + '</td></tr>') htmlList.append('</table>') return '\n'.join(htmlList)
def getMeaningSection(self, inputString): """ Gets a list of entries for the given character string, sorted by reading with annotated alternative character writing, audio and vocab handle. """ def getAudio(filePath): return (' <a class="audio" href="#play(%s)">%s</a>' % (urllib.quote(filePath.encode('utf8')), gettext('Listen'))) #audioHtml = ' <a class="audio" href="#" onclick="new Audio(\'%s\').play(); return false;">%s</a>' \ #% (urllib.quote(filePath.encode('utf8')), gettext('Listen')) #audioHtml = ' <audio src="%s" id="audio_%s" autoplay=false></audio><a class="audio" href="#" onClick="document.getElementById(\'audio_%s\').play(); return false;">%s</a>' \ #% (urllib.quote(filePath.encode('utf8')), reading, reading, gettext('Listen')) readings = [] translations = {} translationIndex = {} alternativeHeadwords = [] alternativeHeadwordIndex = {} # TODO index calculation is broken, e.g. 说 # TODO cache dictResult = self._dictionary.getForHeadword(inputString) for idx, entry in enumerate(dictResult): _, charStringAlt, reading, translation = entry # get unique sorted readings if reading not in readings: readings.append(reading) # save translation, take care of double entries if reading not in translations: translations[reading] = [] translationIndex[reading] = idx if translation not in translations[reading]: translations[reading].append(translation) # save alternative headword, save link to translation if charStringAlt not in alternativeHeadwords: alternativeHeadwords.append(charStringAlt) alternativeHeadwordIndex[charStringAlt] = [] # save link to translation alternativeHeadwordIndex[charStringAlt].append( translations[reading].index(translation)) htmlList = [] # show alternative headword when a) several different ones exist, # b) several entries exist, c) different to headword if self.showAlternativeHeadwords and alternativeHeadwords \ and (len(alternativeHeadwords) > 1 \ or inputString not in alternativeHeadwords): altHeadwordHtml = [] for altHeadword in alternativeHeadwords: if len(inputString) > 1: className = "word" else: className = "character" entry = '<span class="%s">' % className \ + '<a class="character" href="#lookup(%s)">%s</a></span>' \ % (util.encodeBase64(altHeadword), altHeadword) if len(readings) > 1 or len(translations[readings[0]]) > 1: indices = [str(i + 1) for i \ in alternativeHeadwordIndex[altHeadword]] altHeadwordHtml.append('<li>' + entry \ + '<span class="alternativeHeadwordIndex">%s</span>' \ % ' '.join(indices) \ + '</li>') else: altHeadwordHtml.append('<li>%s</li>' % entry) htmlList.append('<p><ul class="alternativeHeadword">%s</ul></p>' \ % ''.join(altHeadwordHtml)) # show entries if readings: htmlList.append('<table class="meaning">') for reading in readings: # get audio if available #filePath, audioHtml = getAudio(reading) filePath, audioHtml = ('', '') # TODO # get reading readingEntry = '<a class="reading" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(reading), self._getReadingRepresentation(reading, forceBlocksOfFor=False)) # get translations translationEntries = [] for translation in translations[reading]: translationEntries.append('<li class="translation">' \ + '<a class="addVocabulary" ' \ + 'href="#addvocab(%s;%s;%s;%s)"></a>' \ % (util.encodeBase64(inputString), util.encodeBase64(reading), util.encodeBase64(translation), util.encodeBase64(filePath)) \ + self._getTranslationRepresentation(translation) \ + '</li>') translationString = ''.join(translationEntries) # create table entry htmlList.append('<tr class="meaningEntry">' \ + '<td class="reading">%s%s</td>' \ % (readingEntry, audioHtml) \ + '<td><ol start="%d">%s</ol></td>' \ % (translationIndex[reading] + 1, translationString) \ + '</tr>') htmlList.append('</table>') else: htmlList.append('<span class="meta">%s</span>' \ % gettext('No dictionary entries found')) return '\n'.join(htmlList)
def getCharacterForRadical(self, radicalIndex, includeAllComponents=False): """Gets a list of characters classified under the given radical.""" # group by residual stroke count characterGroups = self.charDB.getCharacterListForKangxiRadicalIndex( radicalIndex, includeAllComponents=includeAllComponents) htmlList = [] # show main radical form htmlList.append('<h3>%s</h3>' \ % (gettext('Radical %(radical_index)d') \ % {'radical_index': radicalIndex})) charLinks = [] for strokeCount in sorted(characterGroups['radical'].keys()): for char in sorted(characterGroups['radical'][strokeCount]): charLinks.append('<span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>') htmlList.append(' '.join(charLinks)) radicalEntryDict = self.charDB.getRadicalDictionaryEntries() _, meaning = radicalEntryDict.get(radicalIndex, (None, None)) if meaning: htmlList.append(' <span class="translation">%s</span>' % meaning) radicalForms = self.charDB.kangxiRadicalForms _, strokeCount, _, _ = radicalForms[radicalIndex] if strokeCount: htmlList.append(' <span class="strokecount">(%s)</span>' \ % (ngettext('%(strokes)d stroke', '%(strokes)d strokes', strokeCount) % {'strokes': strokeCount})) htmlList.append('<h3>%s</h3>' % gettext('Characters')) # list sorted by residual stroke count if not characterGroups[None]: htmlList.append('<span class="meta">%s</span>' \ % gettext('no results found for the selected character domain')) else: htmlList.append('<table class="searchResult">') for strokeCount in sorted(characterGroups[None].keys()): if type(strokeCount) not in (type(0), type(0L)): # sort out non stroke count groups continue htmlList.append('<tr>' \ + '<th class="strokeCount">+%s</th><td>' % strokeCount) charLinks = [] for char in sorted(characterGroups[None][strokeCount]): charLinks.append('<span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>') htmlList.append(' '.join(charLinks)) htmlList.append('</td></tr>') # Add characters without stroke count information if None in characterGroups[None]: htmlList.append('<tr>' \ + '<th class="strokeCount">%s</th><td>' % gettext('Unknown')) charLinks = [] for char in sorted(characterGroups[None][None]): charLinks.append('<span class="character">' \ + '<a class="character" href="#lookup(%s)">%s</a>' \ % (util.encodeBase64(char), char) \ + '</span>') htmlList.append(' '.join(charLinks)) htmlList.append('</td></tr>') htmlList.append('</table>') return "\n".join(htmlList)