Ejemplo n.º 1
0
Archivo: deck.py Proyecto: ChYi/libanki
 def _renderQA(self, model, gname, data):
     "Returns hash of id, question, answer."
     # data is [cid, fid, mid, gid, ord, tags, flds]
     # unpack fields and create dict
     flist = splitFields(data[6])
     fields = {}
     for (name, (idx, conf)) in model.fieldMap().items():
         fields[name] = flist[idx]
         if fields[name]:
             fields[name] = '<span class="fm%s-%s">%s</span>' % (
                 hexifyID(data[2]), hexifyID(idx), fields[name])
         else:
             fields[name] = ""
     fields['Tags'] = data[5]
     fields['Model'] = model.name
     fields['Group'] = gname
     template = model.templates[data[4]]
     fields['Template'] = template['name']
     # render q & a
     d = dict(id=data[0])
     for (type, format) in (("q", template['qfmt']), ("a", template['afmt'])):
         if type == "q":
             format = format.replace("cloze:", "cq:")
         else:
             if model.conf['clozectx']:
                 name = "cactx:"
             else:
                 name = "ca:"
             format = format.replace("cloze:", name)
         fields = runFilter("mungeFields", fields, model, gname, data, self)
         html = anki.template.render(format, fields)
         d[type] = runFilter(
             "mungeQA", html, type, fields, model, gname, data, self)
     return d
Ejemplo n.º 2
0
def rubify(txt):
    expr = '<span class="fm%s">' % hexifyID(
        [x.id for x in mw.currentCard.fact.model.fieldModels
         if x.name == "Expression"][0])
    read = '<span class="fm%s">' % hexifyID(
        [x.id for x in mw.currentCard.fact.model.fieldModels
         if x.name == "Reading"][0])
    txt = re.sub("([^ >]+?)\[(.+?)\]", """\
<span class="ezRuby" title="\\2">\\1</span>""", txt)
    txt = re.sub("> +", ">", txt)
    txt = re.sub(" +<", "<", txt)
    return txt
Ejemplo n.º 3
0
 def genCSS(self):
     if not self.id:
         return ""
     # fields
     css = "".join(self._fieldCSS(
         ".fm%s-%s" % (hexifyID(self.id), hexifyID(f['ord'])),
         (f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre']))
         for f in self.fields)
     # templates
     css += "".join(".cm%s-%s {text-align:%s;background:%s}\n" % (
         hexifyID(self.id), hexifyID(t['ord']),
         ("center", "left", "right")[t['align']], t['bg'])
             for t in self.templates)
     return css
Ejemplo n.º 4
0
 def genCSS(self):
     if not self.id:
         return ""
     # fields
     css = "".join(
         self._fieldCSS(
             ".fm%s-%s" % (hexifyID(self.id), hexifyID(f['ord'])), (
                 f['font'], f['qsize'], f['qcol'], f['rtl'], f['pre']))
         for f in self.fields)
     # templates
     css += "".join(".cm%s-%s {text-align:%s;background:%s}\n" %
                    (hexifyID(self.id), hexifyID(t['ord']),
                     ("center", "left", "right")[t['align']], t['bg'])
                    for t in self.templates)
     return css
Ejemplo n.º 5
0
def formatQA(cid, mid, fact, tags, cm, deck):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:" + k] = stripHTML(v[1])
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat), ("answer", cm.aformat)):
        # convert old style
        format = re.sub("%\((.+?)\)s", "{{\\1}}", format)
        # allow custom rendering functions & info
        fields = runFilter("prepareFields", fields, cid, mid, fact, tags, cm,
                           deck)
        html = render(format, fields)
        d[type] = runFilter("formatQA", html, type, cid, mid, fact, tags, cm,
                            deck)
    return d
Ejemplo n.º 6
0
 def onDelete(self):
     model = self.selectedModel()
     row = self.dialog.modelsList.currentRow()
     if not model:
         return
     if len(self.d.models) < 2:
         ui.utils.showWarning(_("Please add another model first."),
                              parent=self)
         return
     if self.d.s.scalar("select 1 from sources where id=:id",
                        id=model.source):
         ui.utils.showWarning(_("This model is used by deck source:\n"
                                "%s\nYou will need to remove the source "
                                "first.") % hexifyID(model.source))
         return
     count = self.d.modelUseCount(model)
     if count:
         if not ui.utils.askUser(
             _("This model is used by %d facts.\n"
               "Are you sure you want to delete it?\n"
               "If you delete it, these cards will be lost.")
             % count, parent=self):
             return
     self.d.deleteModel(model)
     self.updateModelsList()
     self.dialog.modelsList.setCurrentRow(row)
     self.parent.reset()
Ejemplo n.º 7
0
 def onDelete(self):
     model = self.selectedModel()
     row = self.dialog.modelsList.currentRow()
     if not model:
         return
     if len(self.d.models) < 2:
         ui.utils.showWarning(_("Please add another model first."),
                              parent=self)
         return
     if self.d.s.scalar("select 1 from sources where id=:id",
                        id=model.source):
         ui.utils.showWarning(_("This model is used by deck source:\n"
                                "%s\nYou will need to remove the source "
                                "first.") % hexifyID(model.source))
         return
     count = self.d.modelUseCount(model)
     if count:
         if not ui.utils.askUser(
             _("This model is used by %d facts.\n"
               "Are you sure you want to delete it?\n"
               "If you delete it, these cards will be lost.")
             % count, parent=self):
             return
     self.d.deleteModel(model)
     self.updateModelsList()
     self.dialog.modelsList.setCurrentRow(row)
Ejemplo n.º 8
0
def formatQA(cid, mid, fact, tags, cm, deck,  build=False):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:"+k] = stripHTML(v[1])
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (
                hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat),
                           ("answer", cm.aformat)):
        # convert old style
        format = re.sub("%\((.+?)\)s", "{{\\1}}", format)
        # allow custom rendering functions & info
        fields = runFilter("prepareFields", fields, cid, mid, fact, tags, cm, deck)
        html = render(format, fields)
        d[type] = runFilter("formatQA", html, type, cid, mid, fact, tags, cm, deck,  build)
    return d
Ejemplo n.º 9
0
def formatQA(cid, mid, fact, tags, cm):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:"+k] = v[1]
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (
                hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat),
                           ("answer", cm.aformat)):
        try:
            html = format % fields
        except (KeyError, TypeError, ValueError):
            html = _("[invalid question/answer format]")
        d[type] = html
    return d
Ejemplo n.º 10
0
def getReading(card):
    if not "[" in card.fact.get(READING, ""):
        return
    # get the reading field
    read = [x.id for x in card.fact.model.fieldModels if x.name == READING]
    if not read:
        return
    return '<span class="fm%s">' % hexifyID(read[0])
Ejemplo n.º 11
0
def getReading(card):
    if not "[" in card.fact.get(READING, ""):
        return
    # get the reading field
    read = [x.id for x in card.fact.model.fieldModels
            if x.name == READING]
    if not read:
        return
    return '<span class="fm%s">' % hexifyID(read[0])
Ejemplo n.º 12
0
def filterHint(a, currentCard):
    """If we are showing the hint, filter out the ANSWER_FIELDS"""
    if mw.state == "showHint":
        fieldIDs = ["fm" + hexifyID(field.id)
                    for field in currentCard.fact.model.fieldModels
                    if field.name in ANSWER_FIELDS]
        for fid in fieldIDs:
            p = re.compile('<span class="%s">' % fid)
            a = p.sub('<span class="%s" style="visibility:hidden">' % fid,
                      a, re.IGNORECASE)
    return a
Ejemplo n.º 13
0
 def htmlQuestion(self, type="question", align=True):
     div = '''<div class="card%s" id="cm%s%s">%s</div>''' % (
         type[0], type[0], hexifyID(self.cardModelId), getattr(self, type))
     # add outer div & alignment (with tables due to qt's html handling)
     if not align:
         return div
     attr = type + 'Align'
     if getattr(self.cardModel, attr) == 0:
         align = "center"
     elif getattr(self.cardModel, attr) == 1:
         align = "left"
     else:
         align = "right"
     return (("<center><table width=95%%><tr><td align=%s>" % align) + div +
             "</td></tr></table></center>")
Ejemplo n.º 14
0
 def htmlQuestion(self, type="question", align=True):
     div = '''<div class="card%s" id="cm%s%s">%s</div>''' % (
         type[0], type[0], hexifyID(self.cardModelId),
         getattr(self, type))
     # add outer div & alignment (with tables due to qt's html handling)
     if not align:
         return div
     attr = type + 'Align'
     if getattr(self.cardModel, attr) == 0:
         align = "center"
     elif getattr(self.cardModel, attr) == 1:
         align = "left"
     else:
         align = "right"
     return (("<center><table width=95%%><tr><td align=%s>" % align) +
             div + "</td></tr></table></center>")
Ejemplo n.º 15
0
def filterAnswer(txt):
    if (not "Japanese" in mw.currentCard.fact.model.tags and
        not "Mandarin" in mw.currentCard.fact.model.tags and
        not "Cantonese" in mw.currentCard.fact.model.tags):
        return txt
    if not "[" in mw.currentCard.fact.get('Reading', ""):
        return txt
    # get the reading field
    read = [x.id for x in mw.currentCard.fact.model.fieldModels
            if x.name == "Reading"]
    if not read:
        return txt
    read = '<span class="fm%s">' % hexifyID(read[0])
    # replace
    def repl(match):
        return read + rubify(match.group(1)) + "</span>"
    txt = re.sub("%s(.*?)</span>" % read, repl, txt)
    return txt
def formatQAAsImage(html, type, cid, mid, fact, tags, cm, deck):
  
  # build up the html 
  div = '''<div class="card%s" id="cm%s%s">%s</div>''' % (
            type[0], type[0], hexifyID(cm.id),
            html)

  attr = type + 'Align'
  if getattr(cm, attr) == 0:
      align = "center"
  elif getattr(cm, attr) == 1:
      align = "left"
  else:
      align = "right"
  html = (("<center><table width=95%%><tr><td align=%s>" % align) +
          div + "</td></tr></table></center>")
  
  t = "<body><br><center>%s</center></body>" % (html)
  bg = "body { background-color: #fff; }\n"
  html = "<style>\n" + bg + deck.rebuildCSS() + "</style>\n" + t

  # create the web page object
  page = QWebPage()
  page.mainFrame().setHtml(html)

  # size everything all nice
  page = fitContentsInPage(page)  

  image= QImage(page.viewportSize(), QImage.Format_ARGB32_Premultiplied)
  painter = QPainter(image)

  page.mainFrame().render(painter)
  painter.end()
  path = saveImage(image, deck)

  link = u"<img src=\"%s\">" % ( path )
  #print link
  #print html
  return link
Ejemplo n.º 17
0
def formatQA(cid, mid, fact, tags, cm):
    "Return a dict of {id, question, answer}"
    d = {'id': cid}
    fields = {}
    for (k, v) in fact.items():
        fields["text:" + k] = stripHTML(v[1])
        if v[1]:
            fields[k] = '<span class="fm%s">%s</span>' % (hexifyID(v[0]), v[1])
        else:
            fields[k] = u""
    fields['tags'] = tags[0]
    fields['Tags'] = tags[0]
    fields['modelTags'] = tags[1]
    fields['cardModel'] = tags[2]
    # render q & a
    ret = []
    for (type, format) in (("question", cm.qformat), ("answer", cm.aformat)):
        try:
            html = format % fields
        except (KeyError, TypeError, ValueError):
            html = _("[invalid question/answer format]")
        d[type] = runFilter("formatQA", html, type, cid, mid, fact, tags, cm)
    return d
Ejemplo n.º 18
0
 def drawSourcesTable(self):
     self.dialog.sourcesTable.clear()
     self.dialog.sourcesTable.setRowCount(len(self.sources))
     self.dialog.sourcesTable.setColumnCount(2)
     self.dialog.sourcesTable.setHorizontalHeaderLabels(
         QStringList([_("ID"),
                      _("Name")]))
     self.dialog.sourcesTable.horizontalHeader().setResizeMode(
         QHeaderView.Stretch)
     self.dialog.sourcesTable.verticalHeader().hide()
     self.dialog.sourcesTable.setSelectionBehavior(
         QAbstractItemView.SelectRows)
     self.dialog.sourcesTable.setSelectionMode(
         QAbstractItemView.SingleSelection)
     self.sourceItems = []
     n = 0
     for (id, name) in self.sources:
         a = QTableWidgetItem(hexifyID(id))
         b = QTableWidgetItem(name)
         self.sourceItems.append([a, b])
         self.dialog.sourcesTable.setItem(n, 0, a)
         self.dialog.sourcesTable.setItem(n, 1, b)
         n += 1
Ejemplo n.º 19
0
 def syncOneWayDeckName(self):
     return (self.deck.s.scalar("select name from sources where id = :id",
                                id=self.server.deckName) or
             hexifyID(int(self.server.deckName)))
Ejemplo n.º 20
0
 def cssClass(self):
     return "cm%s-%s" % (hexifyID(
         self.model().id), hexifyID(self.template()['ord']))
Ejemplo n.º 21
0
def append_JxPlugin(Answer,Card):
    """Append additional information about kanji and words in answer."""

    

    
    # Guess the type(s) and the relevant content(s) of the Fact
    JxGuessedList = JxMagicalGuess(Card) # that's it. Chose the right name for the right job. This should always work now, lol...


    
    # Get and translate the new CardModel Template
    JxPrefix = u''
    for (Type,Field,Content) in JxGuessedList:
           JxPrefix += JxAbbrev[Type]
    try:
	    JxAnswer = JxLink[JxPrefix + u'-' + Card.cardModel.aformat]
    except KeyError:
            try:
                    JxAnswer = JxLink["D-"+Card.cardModel.aformat]     # in case the right template hasn't been set, we try with the default template "D:"
            except KeyError: 
                    return Answer
                    


    
    # Then create a dictionnary for all data replacement strings...
    
    JxAnswerDict = {
        'F':'','F-Stroke':'',
        'K':'','W':'','S':'','G':'',
        'K-Stroke':'','W-Stroke':'','S-Stroke':'','G-Stroke':'',
        "W-JLPT":'','W-Freq':'',
        'K-JLPT':'','K-Jouyou':'','K-Freq':'',
        'K-Words':'',
        'W-Sentences':''
        }    
    
    # ${F-Types}
    JxAnswerDict['F-Types'] = str(JxGuessedList)    
 
    # ${K}, ${W}, ${S}, ${G}  and  ${K-Stroke}, ${W-Stroke}, ${S-Stroke}, ${G-Stroke}        
    for (Type,Field,Content) in JxGuessedList:
            ShortType = JxAbbrev[Type]
            Stripped = Content.strip()
            JxAnswerDict[ShortType] = Stripped
            KanjiList= [c for c in Stripped if JxIsKanji(c)]
            if ShortType != 'K':
                    JxAnswerDict[ShortType + '-Stroke'] = JxStrokeDisplay(KanjiList,ShortType + '-Stroke')
            else:
                    JxAnswerDict[ShortType + '-Stroke'] = ''.join(KanjiList)
    
    # need those for performance : every tenth second counts if you review 300+ Card a day
    # (the first brutal implementation had sometimes between 0.5s and 2s of lag to display the answer (i.e. make the user wait).
    
    JxK = JxAnswerDict['K']
    JxW = JxAnswerDict['W']
    JxS = JxAnswerDict['S']
    JxG = JxAnswerDict['G']    
    

    # ${F} and ${F-Stroke}
    if JxGuessedList: 
            JxAnswerDict['F'] = JxGuessedList[0][0].strip()
            JxAnswerDict['F-Stroke'] = u"""%s""" % ''.join([c for c in JxGuessedList[0][0].strip() if JxIsKanji(c)])
    
            

    if JxW:
            try:        # ${W-JLPT}
                    JxAnswerDict['W-JLPT'] =  '%s' % MapJLPTTango.String(JxW)
            except KeyError:pass
            
            try:        # ${W-Freq}
                    JxAnswerDict['W-Freq'] =  '%s'  % MapFreqTango.Value(JxW, lambda x:int(100*(log(x+1,2)-log(Jx_Word_MinOccurences+1,2))/(log(Jx_Word_MaxOccurences+1,2)-log(Jx_Word_MinOccurences+1,2)))) 
            except KeyError:pass

            Query = """select expression.factId, expression.value, meaning.value, reading.value from 
            fields as expression, fields as reading, fields as meaning, fieldModels as fmexpression, fieldModels as fmreading, fieldModels as fmmeaning where expression.fieldModelId= fmexpression.id and fmexpression.name in ("%s") and reading.fieldModelId= fmreading.id and fmreading.name="Reading" and reading.factId=expression.factId and meaning.fieldModelId= fmmeaning.id and fmmeaning.name="Meaning" and meaning.factId=expression.factId and
            expression.factId != "%s" and
            expression.value like "%%%s%%" """ % ('","'.join(JxTypeHash[u'Sentence'])+'","'.join(JxTypeHash[u'Word'])+'","'+'","'+JxExpression,Card.factId,JxW)
            result=mw.deck.s.all(Query)
            JxAnswerDict['W-Sentences'] = JxTableDisplay(result,'W-Sentences',u'Sentence')    
            JxAnswerDict['W-Words'] = JxTableDisplay(result,'W-Words',u'Word') #for idioms and compound words    

    if JxK:
            try:        # ${K:JLPT}
                    JxAnswerDict['K-JLPT'] =  '%s' % MapJLPTKanji.String(JxK)
            except KeyError:pass
            
            try:        # ${K:Jouyou}
                    JxAnswerDict['K-Jouyou'] =  '%s' % MapJouyouKanji.String(JxK)
            except KeyError:pass

            try:        # ${K:Freq}    
                    JxAnswerDict['K-Freq'] = '%s'  % MapFreqKanji.Value(JxK, lambda x:int((log(x+1,2)-log(Jx_Kanji_MaxOccurences+1,2))*10+100))
            except KeyError:pass      	       
            
            Query = """select expression.factId, expression.value, meaning.value, reading.value from 
            fields as expression, fields as reading, fields as meaning, fieldModels as fmexpression, fieldModels as fmreading, fieldModels as fmmeaning where expression.fieldModelId= fmexpression.id and fmexpression.name in ("%s") and reading.fieldModelId= fmreading.id and fmreading.name="Reading" and reading.factId=expression.factId and meaning.fieldModelId= fmmeaning.id and fmmeaning.name="Meaning" and meaning.factId=expression.factId and
            expression.factId != "%s" and
            expression.value like "%%%s%%" """ % ('","'.join(JxTypeHash[u'Sentence'])+'","'+'","'.join(JxTypeHash[u'Word'])+'","'+JxExpression,Card.factId,JxK)
            result=mw.deck.s.all(Query)
            JxAnswerDict['K-Words'] = JxTableDisplay(result,'K-Words',u'Word')    
            JxAnswerDict['K-Sentences'] = JxTableDisplay(result,'K-Sentences',u'Sentence')    

    
    from controls import JxSettings
    JxAnswerDict['Css'] = '<style>%s</style>' % JxSettings.Get(u'Css')
    
    # ${<Field>}
    for FieldModel in Card.fact.model.fieldModels:
	    JxAnswerDict[FieldModel.name] = '<span class="fm%s">%s</span>' % (
                hexifyID(FieldModel.id), Card.fact[FieldModel.name])
            
    # ${F-Tags}, ${M-Tags}, ${Tags}
    JxAnswerDict['F-Tags'] = Card.fact.tags
    JxAnswerDict['M-Tags'] = Card.fact.model.tags
    JxAnswerDict['Tags'] = " ".join(set(Card.fact.model.tags.split(" ") + Card.fact.tags.split(" ") + [Card.cardModel.name]))
                
    JxProfile("Fill JxCodes")
    
    JxAnswer = re.sub("\$\{(.*?)\}",lambda x:JxReplace(x,JxAnswerDict),JxAnswer)
    
    JxProfile("Substitutions")
                      
    from controls import JxSettings
    Mode=JxSettings.Get(u'Mode')
    if Mode == "Append": JxAnswer = Answer + JxAnswer
    elif Mode == "Prepend": JxAnswer += Answer


    JxProfile("Concatenation")    
    
    removeHook("drawAnswer",append_JxPlugin)
    JxAnswer = runFilter("drawAnswer",JxAnswer, Card)
    addHook("drawAnswer",append_JxPlugin)
    
    JxProfile("Filter")
    #JxShowProfile()
    return JxAnswer
Ejemplo n.º 22
0
 def cssClass(self):
     return "cm%s-%s" % (hexifyID(self.model().id),
                         hexifyID(self.template()['ord']))
Ejemplo n.º 23
0
 def syncOneWayDeckName(self):
     return (self.deck.s.scalar("select name from sources where id = :id",
                                id=self.server.deckName)
             or hexifyID(int(self.server.deckName)))