# -*- coding: utf-8 -*- # Copyright (C) 2013 Alex Yatskov # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from PyQt4 import QtGui import re def decodeContent(content): encodings = ['utf-8', 'shift_jis', 'euc-jp', 'utf-16'] errors = dict() for encoding in encodings: try: return content.decode(encoding), encoding except UnicodeDecodeError, e: errors[encoding] = e[2] encoding = sorted(errors, key=errors.get, reverse=True)[0] return content.decode(encoding, 'replace'), encoding def stripReadings(content): return re.sub(u'《[^》]+》', unicode(), content) def findSentence(content, position): quotesFwd = {u'「': u'」', u'『': u'』', u"'": u"'", u'"': u'"'} quotesBwd = {u'」': u'「', u'』': u'『', u"'": u"'", u'"': u'"'} terminators = u'。..??!!' quoteStack = list() start = 0 for i in xrange(position, start, -1): c = content[i] if not quoteStack and (c in terminators or c in quotesFwd or c == '\n'): start = i + 1 break if quoteStack and c == quoteStack[0]: quoteStack.pop() elif c in quotesBwd: quoteStack.insert(0, quotesBwd[c]) quoteStack = list() end = len(content) for i in xrange(position, end): c = content[i] if not quoteStack: if c in terminators: end = i + 1 break elif c in quotesBwd: end = i break if quoteStack and c == quoteStack[0]: quoteStack.pop() elif c in quotesFwd: quoteStack.insert(0, quotesFwd[c]) return content[start:end].strip() def formatFields(fields, markup): result = dict() for field, value in fields.items(): result[field] = value.format(**markup) return result def splitTags(tags): return filter(lambda tag: tag.strip(), re.split('[;,\s]', tags)) def markupVocabExp(definition): return { 'expression': definition['expression'], 'reading': definition['reading'], 'glossary': definition['glossary'], 'sentence': definition.get('sentence') } def markupVocabReading(definition): return { 'expression': definition['reading'], 'reading': unicode(), 'glossary': definition['glossary'], 'sentence': definition.get('sentence') } def copyVocabDefs(definitions): text = unicode() for definition in definitions: if definition['reading']: text += u'{expression}\t{reading}\t{glossary}\n'.format(**definition) else: text += u'{expression}\t{meanings}\n'.format(**definition) QtGui.QApplication.clipboard().setText(text) def buildVocabDef(definition, factIndex, factQuery): reading = unicode() if definition['reading']: reading = u'[{0}]'.format(definition['reading']) rules = unicode() if len(definition['rules']) > 0: rules = ' • '.join(definition['rules']) rules = '<{0}>
'.format(rules) links = ''.format(factIndex) if factQuery: if factQuery('vocab', markupVocabExp(definition)): links += ''.format(factIndex) if factQuery('vocab', markupVocabReading(definition)): links += ''.format(factIndex) html = u""" {0} {1} {2}
{3}
{4}
""".format(links, definition['expression'], reading, definition['glossary'], rules) return html def buildVocabDefs(definitions, factQuery): palette = QtGui.QApplication.palette() toolTipBg = palette.color(QtGui.QPalette.Window).name() toolTipFg = palette.color(QtGui.QPalette.WindowText).name() html = u""" """.format(toolTipBg, toolTipFg) if len(definitions) > 0: for i, definition in enumerate(definitions): html += buildVocabDef(definition, i, factQuery) else: html += """

No definitions to display.

Mouse over text with the middle mouse button or shift key pressed to search.

You can also also input terms in the search box below.

""" html += '' return html