Ejemplo n.º 1
0
def myLoadNote(self):
    self.web.eval(js_code)
    if self.stealFocus:
        field = self.currentField
    else:
        field = -1
    if not self._loaded:
        # will be loaded when page is ready
        return
    data = []
    for fld, val in self.note.items():
        data.append((fld, self.mw.col.media.escapeImages(val)))
    ###########################################################
    sticky = []
    model = self.note.model()
    for fld in model['flds']:
        sticky.append(fld['sticky'])
    ###########################################################
    self.web.eval("setFrozenFields(%s, %s, %d);" % (
        json.dumps(data), json.dumps(sticky), field))
    self.web.eval("setFonts(%s);" % (
        json.dumps(self.fonts())))
    self.checkValid()
    self.widget.show()
    if self.stealFocus:
        self.web.setFocus()
Ejemplo n.º 2
0
 def doPaste(self, html, internal, extended=False):
     html = self._pastePreFilter(html, internal)
     if extended:
         extended = "true"
     else:
         extended = "false"
     self.web.eval("pasteHTML(%s, %s, %s);" % (
         json.dumps(html), json.dumps(internal), extended))
Ejemplo n.º 3
0
def _addColVars(db, g, gc, c):
    db.execute(
        """
update col set conf = ?, decks = ?, dconf = ?""",
        json.dumps(c),
        json.dumps({"1": g}),
        json.dumps({"1": gc}),
    )
Ejemplo n.º 4
0
    def dump(self) :
        fp = Storage(self.word).getPath() + self.word + '.mtp'
        arr_data = []
        for e in self.data :
            st = e.dumps()
            arr_data.append(st)

        arr_data_all = [json.dumps(self.stars), json.dumps(arr_data)]

        with open(fp, 'w') as f:
              json.dump(arr_data_all, f)
Ejemplo n.º 5
0
    def mediaChangesZip(self):
        f = StringIO()
        z = zipfile.ZipFile(f, "w", compression=zipfile.ZIP_DEFLATED)

        fnames = []
        # meta is list of (fname, zipname), where zipname of None
        # is a deleted file
        meta = []
        sz = 0

        for c, (fname, csum) in enumerate(self.db.execute(
                        "select fname, csum from media where dirty=1"
                        " limit %d"%SYNC_ZIP_COUNT)):

            fnames.append(fname)
            normname = unicodedata.normalize("NFC", fname)

            if csum:
                self.col.log("+media zip", fname)
                z.write(fname, str(c))
                meta.append((normname, str(c)))
                sz += os.path.getsize(fname)
            else:
                self.col.log("-media zip", fname)
                meta.append((normname, ""))

            if sz >= SYNC_ZIP_SIZE:
                break

        z.writestr("_meta", json.dumps(meta))
        z.close()
        return f.getvalue(), fnames
Ejemplo n.º 6
0
 def zipAdded(self):
     "Add files to a zip until over SYNC_ZIP_SIZE/COUNT. Return zip data."
     f = StringIO()
     z = zipfile.ZipFile(f, "w", compression=zipfile.ZIP_DEFLATED)
     sz = 0
     cnt = 0
     files = {}
     cur = self.db.execute(
         "select fname from log where type = ?", MEDIA_ADD)
     fnames = []
     while 1:
         fname = cur.fetchone()
         if not fname:
             # add a flag so the server knows it can clean up
             z.writestr("_finished", "")
             break
         fname = fname[0]
         fnames.append([fname])
         z.write(fname, str(cnt))
         files[str(cnt)] = fname
         sz += os.path.getsize(fname)
         if sz > SYNC_ZIP_SIZE or cnt > SYNC_ZIP_COUNT:
             break
         cnt += 1
     z.writestr("_meta", json.dumps(files))
     z.close()
     return f.getvalue(), fnames
Ejemplo n.º 7
0
def append_kanji_info():
    """Append additional information about the kanji of the current card."""
    global enabled
    if not enabled:
        return

    done = {}
    info = "<p></p>"

    for item in mw.reviewer.card.note().items():
        for u in item[1]:
            # prevent showing same kanji twice:
            if u not in done:
                done[u] = 1

                if u in kanji_info:
                    # FIXME:   I'd like to get rid of the kanji mouseover title,
                    # FIXME::  but there does not seem to be a way to get a
                    # FIXME::  furigana-alike formatting in simple HTML.
                    info += """ <span style="%s" title="%s">%s</span> """ % \
                        ("color:#000000; font-family:KanjiStrokeOrders; font-size:128px;",
                         kanji_info[u], u)

    # if there is any info, add it to the buffer
    if len(info):
        # I have no idea what I'm doing. Seriously, JavaScript?!
        mw.reviewer.web.eval("""$("div")[0].innerHTML+=%s;""" % json.dumps(info))
Ejemplo n.º 8
0
    def _showQuestion(self):
        self._reps += 1
        self.state = "question"
        self.typedAnswer = None
        c = self.card
        # grab the question and play audio
        if c.isEmpty():
            q = _("""\
The front of this card is empty. Please run Tools>Empty Cards.""")
        else:
            q = c.q()
        if self.autoplay(c):
            playFromText(q)
        # render & update bottom
        q = self._mungeQA(q)
        klass = "card card%d" % (c.ord+1)
        self.web.eval("_updateQA(%s, false, '%s');" % (json.dumps(q), klass))
        self._toggleStar()
        if self._bottomReady:
            self._showAnswerButton()
        # if we have a type answer field, focus main web
        if self.typeCorrect:
            self.mw.web.setFocus()
        # user hook
        runHook('showQuestion')
Ejemplo n.º 9
0
 def exportInto(self, path):
     # open a zip file
     z = zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED, allowZip64=True)
     media = self.doExport(z, path)
     # media map
     z.writestr("media", json.dumps(media))
     z.close()
Ejemplo n.º 10
0
    def _showQuestion(self):
        self._reps += 1
        self.state = "question"
        self.typedAnswer = None
        c = self.card
        # grab the question and play audio
        if c.isEmpty():
            q = _("""\
The front of this card is empty. Please run Tools>Empty Cards.""")
        else:
            q = c.q()
        if self.autoplay(c):
            playFromText(q)
        # render & update bottom
        q = self._mungeQA(q)
        q = runFilter("prepareQA", q, c, "reviewQuestion")

        bodyclass = bodyClass(self.mw.col, c)

        self.web.eval("_showQuestion(%s,'%s');" % (json.dumps(q), bodyclass))
        self._drawFlag()
        self._drawMark()
        self._showAnswerButton()
        # if we have a type answer field, focus main web
        if self.typeCorrect:
            self.mw.web.setFocus()
        # user hook
        runHook('showQuestion')
Ejemplo n.º 11
0
Archivo: sync.py Proyecto: Stvad/anki
 def mediatest(self, cmd):
     self.postVars = dict(
         k=self.hkey,
     )
     return self._dataOnly(
         self.req("newMediaTest", io.BytesIO(
             json.dumps(dict(cmd=cmd)).encode("utf8"))))
Ejemplo n.º 12
0
 def insert_markup_in_field(self, markup, field):
     """
     Put markup in the specified field.
     """
     self.editor_instance.web.eval("""
         document.getElementById('f%s').innerHTML = %s;
     """ % (field, json.dumps(unicode(markup))))
Ejemplo n.º 13
0
Archivo: sync.py Proyecto: dper/anki
 def mediaChanges(self, **kw):
     self.postVars = dict(
         sk=self.skey,
     )
     resp = json.loads(
         self.req("mediaChanges", StringIO(json.dumps(kw))))
     return self._dataOnly(resp)
Ejemplo n.º 14
0
 def _migrateModels(self):
     import anki.models
     db = self.db
     times = {}
     mods = {}
     for row in db.all(
         "select id, name from models"):
         # use only first 31 bits if not old anki id
         t = abs(row[0])
         if t > 4294967296:
             t >>= 32
         assert t > 0
         m = anki.models.defaultModel.copy()
         m['id'] = t
         m['name'] = row[1]
         m['mod'] = intTime()
         m['tags'] = []
         m['flds'] = self._fieldsForModel(row[0])
         m['tmpls'] = self._templatesForModel(row[0], m['flds'])
         mods[m['id']] = m
         db.execute("update notes set mid = ? where mid = ?", t, row[0])
     # save and clean up
     db.execute("update col set models = ?", json.dumps(mods))
     db.execute("drop table fieldModels")
     db.execute("drop table cardModels")
     db.execute("drop table models")
Ejemplo n.º 15
0
 def save_prefs(prefs):
     """
     Save the preferences to disk, base64 encoded.
     """
     encoded_prefs = base64.b64encode(json.dumps(prefs))
     with codecs.open(PrefHelper.get_preference_path(), "w", encoding="utf8") as f:
         f.write(encoded_prefs)
Ejemplo n.º 16
0
Archivo: sync.py Proyecto: dper/anki
 def mediatest(self, cmd):
     self.postVars = dict(
         k=self.hkey,
     )
     return self._dataOnly(json.loads(
         self.req("newMediaTest", StringIO(
             json.dumps(dict(cmd=cmd))))))
Ejemplo n.º 17
0
 def _migrateModels(self):
     import anki.models
     db = self.db
     times = {}
     mods = {}
     for row in db.all(
         "select id, name from models"):
         while 1:
             t = intTime(1000)
             if t not in times:
                 times[t] = True
                 break
         m = anki.models.defaultModel.copy()
         m['id'] = t
         m['name'] = row[1]
         m['mod'] = intTime()
         m['tags'] = []
         m['flds'] = self._fieldsForModel(row[0])
         m['tmpls'] = self._templatesForModel(row[0], m['flds'])
         mods[m['id']] = m
         db.execute("update notes set mid = ? where mid = ?", t, row[0])
     # save and clean up
     db.execute("update col set models = ?", json.dumps(mods))
     db.execute("drop table fieldModels")
     db.execute("drop table cardModels")
     db.execute("drop table models")
Ejemplo n.º 18
0
    def flush(self, mod=None):
        "Flush state to DB, updating mod time."
        self.mod = intTime(1000) if mod is None else mod
        self.db.execute(
            """update col set
crt=?, mod=?, scm=?, dty=?, usn=?, ls=?, conf=?""",
            self.crt, self.mod, self.scm, self.dty,
            self._usn, self.ls, json.dumps(self.conf))
Ejemplo n.º 19
0
Archivo: sync.py Proyecto: Sushant/anki
 def meta(self):
     ret = self.req(
         "meta", StringIO(json.dumps(dict(v=SYNC_VER))),
         badAuthRaises=False)
     if not ret:
         # invalid auth
         return
     return json.loads(ret)
Ejemplo n.º 20
0
 def loadNote(self):
     if not self.note:
         return
     field = self.currentField
     if not self._loaded:
         # will be loaded when page is ready
         return
     data = []
     for fld, val in self.note.items():
         data.append((fld, self.escapeImages(val)))
     self.web.eval("setFields(%s, %d);" % (
         json.dumps(data), field))
     self.web.eval("setFonts(%s);" % (
         json.dumps(self.fonts())))
     self.checkValid()
     self.widget.show()
     self.web.setFocus()
Ejemplo n.º 21
0
Archivo: sync.py Proyecto: Stvad/anki
 def begin(self):
     self.postVars = dict(
         k=self.hkey,
         v="ankidesktop,%s,%s"%(anki.version, platDesc())
     )
     ret = self._dataOnly(self.req(
         "begin", io.BytesIO(json.dumps(dict()).encode("utf8"))))
     self.skey = ret['sk']
     return ret
Ejemplo n.º 22
0
 def meta(self):
     ret = self.req(
         "meta", StringIO(json.dumps(dict(
             v=SYNC_VER, cv="ankidesktop,%s,%s"%(anki.version, platDesc())))),
         badAuthRaises=False)
     if not ret:
         # invalid auth
         return
     return json.loads(ret)
Ejemplo n.º 23
0
 def hostKey(self, user, pw):
     "Returns hkey or none if user/pw incorrect."
     self.postVars = dict()
     ret = self.req("hostKey", StringIO(json.dumps(dict(u=user, p=pw))), badAuthRaises=False)
     if not ret:
         # invalid auth
         return
     self.hkey = json.loads(ret)["key"]
     return self.hkey
Ejemplo n.º 24
0
def json_dump_and_compress(data):
    """
    Take a string `data` and JSONify it. Return the resultant string, encoded
    in base64.
    """

    ret = unicode(base64.b64encode(json.dumps(data)))
    assert isinstance(ret, unicode), "Output `ret` is not Unicode"
    return ret
Ejemplo n.º 25
0
Archivo: sync.py Proyecto: dper/anki
 def begin(self):
     self.postVars = dict(
         k=self.hkey,
         v="ankidesktop,%s,%s"%(anki.version, platDesc())
     )
     ret = self._dataOnly(json.loads(self.req(
         "begin", StringIO(json.dumps(dict())))))
     self.skey = ret['sk']
     return ret
def myBridge(self, str, _old=None):
    if str.startswith("autocomplete"):
        (type, jsonText) = str.split(":", 1)
        result = json.loads(jsonText)
        text = self.mungeHTML(result["text"])

        # bail out if the user hasn't actually changed the field
        previous = "%d:%s" % (self.currentField, text)
        if self.prevAutocomplete == previous:
            return
        self.prevAutocomplete = previous

        if text == "" or len(text) > 500 or self.note is None:
            self.web.eval("$('.autocomplete').remove();")
            return

        field = self.note.model()["flds"][self.currentField]

        if field["name"] in noAutocompleteFields:
            field["no_autocomplete"] = True

        if "no_autocomplete" in field.keys() and field["no_autocomplete"]:
            return

        # find a value from the same model and field whose
        # prefix is what the user typed so far
        query = "'note:%s' '%s:%s*'" % (self.note.model()["name"], field["name"], text)

        col = self.note.col
        res = col.findCards(query, order=True)

        if len(res) == 0:
            self.web.eval("$('.autocomplete').remove();")
            return

        # pull out the full value
        value = col.getCard(res[0]).note().fields[self.currentField]

        escaped = json.dumps(value)

        self.web.eval(
            """
            $('.autocomplete').remove();

            if (currentField) {
                $('<div class="autocomplete">' + %s + '</div>').click(function () {
                    currentField.focus();
                    currentField.innerHTML = %s;
                    saveField("key");
                }).insertAfter(currentField)
            }
        """
            % (escaped, escaped)
        )
    else:
        _old(self, str)
def highlight_code(self):
    addon_conf = mw.col.conf['syntax_highlighting_conf']

    #  Do we want line numbers? linenos is either true or false according
    # to the user's preferences
    linenos = addon_conf['linenos']

    style = get_style_by_name(addon_conf['style'])

    centerfragments = addon_conf['centerfragments']
    
    selected_text = self.web.selectedText()
    if selected_text:
        #  Sometimes, self.web.selectedText() contains the unicode character
        # '\u00A0' (non-breaking space). This character messes with the
        # formatter for highlighted code. To correct this, we replace all
        # '\u00A0' characters with regular space characters
        code = selected_text.replace(u'\u00A0', ' ')
    else:
        clipboard = QApplication.clipboard()
        # Get the code from the clipboard
        code = clipboard.text()
    
    langAlias = self.codeHighlightLangAlias
    
    # Select the lexer for the correct language
    my_lexer = get_lexer_by_name(langAlias, stripall=True)
    # Tell pygments that we will be generating HTML without CSS.
    # HTML without CSS may take more space, but it's self contained.
    
    my_formatter = HtmlFormatter(linenos=linenos, noclasses=True, font_size=16, style=style)
    
    if linenos:
       if centerfragments:
            pretty_code = "".join(["<center>",
                                 highlight(code, my_lexer, my_formatter),
                                 "</center><br>"])
       else:
            pretty_code = "".join([highlight(code, my_lexer, my_formatter),
                                 "<br>"])
    # TODO: understand why this is neccessary
    else:
        if centerfragments:
            pretty_code = "".join(["<center><table><tbody><tr><td>",
                                   highlight(code, my_lexer, my_formatter),
                                   "</td></tr></tbody></table></center><br>"])
        else:
            pretty_code = "".join(["<table><tbody><tr><td>",
                                   highlight(code, my_lexer, my_formatter),
                                   "</td></tr></tbody></table><br>"])

    # These two lines insert a piece of HTML in the current cursor position
    self.web.eval("document.execCommand('inserthtml', false, %s);"
                  % json.dumps(pretty_code))
Ejemplo n.º 28
0
Archivo: sync.py Proyecto: Stvad/anki
 def hostKey(self, user, pw):
     "Returns hkey or none if user/pw incorrect."
     self.postVars = dict()
     ret = self.req(
         "hostKey", io.BytesIO(json.dumps(dict(u=user, p=pw)).encode("utf8")),
         badAuthRaises=False)
     if not ret:
         # invalid auth
         return
     self.hkey = json.loads(ret.decode("utf8"))['key']
     return self.hkey
Ejemplo n.º 29
0
 def exportInto(self, path):
     # open a zip file
     z = zipfile.ZipFile(path, "w", zipfile.ZIP_DEFLATED, allowZip64=True)
     # if all decks and scheduling included, full export
     if self.includeSched and not self.did:
         media = self.exportVerbatim(z)
     else:
         # otherwise, filter
         media = self.exportFiltered(z, path)
     # media map
     z.writestr("media", json.dumps(media))
     z.close()
Ejemplo n.º 30
0
 def checkValid(self):
     cols = []
     err = None
     for f in self.note.fields:
         cols.append("#fff")
     err = self.note.dupeOrEmpty()
     if err == 2:
         cols[0] = "#fcc"
         self.web.eval("showDupes();")
     else:
         self.web.eval("hideDupes();")
     self.web.eval("setBackgrounds(%s);" % json.dumps(cols))
Ejemplo n.º 31
0
 def _run(self, cmd, data):
     return json.loads(self.req(cmd, StringIO(json.dumps(data))))
Ejemplo n.º 32
0
 def mediaChanges(self, **kw):
     self.postVars = dict(sk=self.skey, )
     resp = json.loads(self.req("mediaChanges", StringIO(json.dumps(kw))))
     return self._dataOnly(resp)
Ejemplo n.º 33
0
def highlight_code(ed):
    addon_conf = mw.col.get_config('syntax_highlighting_conf')

    #  Do we want line numbers? linenos is either true or false according
    # to the user's preferences
    linenos = addon_conf['linenos']

    centerfragments = addon_conf['centerfragments']

    # Do we want to use css classes or have formatting directly in HTML?
    # Using css classes takes up less space and gives the user more
    # customization options, but is less self-contained as it requires
    # setting the styling on every note type where code is used
    noclasses = not addon_conf['cssclasses']

    selected_text = ed.web.selectedText()
    if selected_text:
        #  Sometimes, self.web.selectedText() contains the unicode character
        # '\u00A0' (non-breaking space). This character messes with the
        # formatter for highlighted code. To correct this, we replace all
        # '\u00A0' characters with regular space characters
        code = selected_text.replace('\u00A0', ' ')
    else:
        clipboard = QApplication.clipboard()
        # Get the code from the clipboard
        code = clipboard.text()

    langAlias = ed.codeHighlightLangAlias

    # Select the lexer for the correct language
    try:
        my_lexer = get_lexer_by_name(langAlias, stripall=True)
    except ClassNotFound as e:
        print(e)
        showError(ERR_LEXER, parent=ed.parentWindow)
        return False

    # Create html formatter object including flags for line nums and css classes
    try:
        my_formatter = HtmlFormatter(linenos=linenos,
                                     noclasses=noclasses,
                                     font_size=16,
                                     style=STYLE)
    except ClassNotFound as e:
        print(e)
        showError(ERR_STYLE, parent=ed.parentWindow)
        return False

    if linenos:
        if centerfragments:
            pretty_code = "".join([
                "<center>",
                highlight(code, my_lexer, my_formatter), "</center><br>"
            ])
        else:
            pretty_code = "".join(
                [highlight(code, my_lexer, my_formatter), "<br>"])
    # TODO: understand why this is neccessary
    else:
        if centerfragments:
            pretty_code = "".join([
                "<center>",
                highlight(code, my_lexer, my_formatter), "</center><br>"
            ])
        else:
            pretty_code = "".join(
                [highlight(code, my_lexer, my_formatter), "<br>"])

    pretty_code = process_html(pretty_code)

    # These two lines insert a piece of HTML in the current cursor position
    ed.web.eval("document.execCommand('inserthtml', false, %s);" %
                json.dumps(pretty_code))
Ejemplo n.º 34
0
 def mediaChanges(self, **kw):
     self.postVars = dict(
         sk=self.skey,
     )
     return self._dataOnly(
         self.req("mediaChanges", io.BytesIO(json.dumps(kw).encode("utf8"))))
Ejemplo n.º 35
0
 def files(self, **kw):
     return self.req("files", StringIO(json.dumps(kw)))
Ejemplo n.º 36
0
 def mediaSanity(self, **kw):
     return self._dataOnly(
         self.req("mediaSanity", io.BytesIO(json.dumps(kw).encode("utf8"))))
Ejemplo n.º 37
0
 def flush(self):
     "Flush the registry if any models were changed."
     if self.changed:
         self.col.db.execute("update col set models = ?",
                             json.dumps(self.models))
         self.changed = False
Ejemplo n.º 38
0
 def addMedia(self, path, canDelete=False):
     html = self._addMedia(path, canDelete)
     self.web.eval("setFormat('inserthtml', %s);" % json.dumps(html))
Ejemplo n.º 39
0
 def _toggleStar(self):
     self.web.eval("_toggleStar(%s);" %
                   json.dumps(self.card.note().hasTag("marked")))
Ejemplo n.º 40
0
 def save_prefs(prefs):
     """
     Save the preferences to disk.
     """
     with codecs.open(PrefHelper.get_preference_path(), "w", encoding="utf8") as f:
         f.write(json.dumps(prefs))
Ejemplo n.º 41
0
 def _showEaseButtons(self):
     self.bottom.web.setFocus()
     middle = self._answerButtons()
     self.bottom.web.eval("showAnswer(%s);" % json.dumps(middle))
Ejemplo n.º 42
0
Archivo: decks.py Proyecto: zzp0/anki
 def flush(self):
     if self.changed:
         self.col.db.execute("update col set decks=?, dconf=?",
                             json.dumps(self.decks), json.dumps(self.dconf))
         self.changed = False
Ejemplo n.º 43
0
def _addColVars(db, g, gc, c):
    db.execute("""
update col set conf = ?, decks = ?, dconf = ?""", json.dumps(c),
               json.dumps({'1': g}), json.dumps({'1': gc}))
def wrap_in_tags(self, tag, class_name=None):
    """
    Wrap selected text in a tag, optionally giving it a class.
    """
    selection = self.web.selectedText()

    if not selection:
        return

    selection = utility.escape_html_chars(selection)

    tag_string_begin = ("<{0} class='{1}'>".format(tag, class_name)
                        if class_name else "<{0}>".format(tag))
    tag_string_end = "</{0}>".format(tag)

    html = self.note.fields[self.currentField]

    if "<li><br /></li>" in html:
        # an empty list means trouble, because somehow Anki will also make the
        # line in which we want to put a <code> tag a list if we continue
        replacement = tag_string_begin + selection + tag_string_end
        self.web.eval("document.execCommand('insertHTML', false, %s);" %
                      json.dumps(replacement))

        self.web.setFocus()
        self.web.eval("focusField(%d);" % self.currentField)
        self.saveNow()

        html_after = self.note.fields[self.currentField]

        if html_after != html:
            # you're in luck!
            return
        else:
            # nothing happened :( this is another Anki bug :( that has to do
            # with <code> tags following <div> tags
            return

    # Due to a bug in Anki or BeautifulSoup, we cannot use a simple
    # wrap operation like with <a>. So this is a very hackish way of making
    # sure that a <code> tag may precede or follow a <div> and that the tag
    # won't eat the character immediately preceding or following it
    pattern = "@%*!"
    len_p = len(pattern)

    # first, wrap the selection up in a pattern that the user is unlikely
    # to use in its own cards
    self.web.eval("wrap('{0}', '{1}')".format(pattern, pattern[::-1]))

    # focus the field, so that changes are saved
    # this causes the cursor to go to the end of the field
    self.web.setFocus()
    self.web.eval("focusField(%d);" % self.currentField)

    self.saveNow()

    html = self.note.fields[self.currentField]

    begin = html.find(pattern)
    end = html.find(pattern[::-1], begin)

    html = (html[:begin] + tag_string_begin + selection + tag_string_end +
            html[end + len_p:])

    # delete the current HTML and replace it by our new & improved one
    self.note.fields[self.currentField] = html

    # reload the note: this is needed on OS X, because it will otherwise
    # falsely show that the formatting of the element at the start of
    # the HTML has spread across the entire note
    self.loadNote()

    # focus the field, so that changes are saved
    self.web.setFocus()
    self.web.eval("focusField(%d);" % self.currentField)
    self.saveNow()
    self.web.setFocus()
    self.web.eval("focusField(%d);" % self.currentField)
Ejemplo n.º 45
0
 def doPaste(self, html, internal):
     if not internal:
         html = self._pastePreFilter(html)
     self.web.eval("pasteHTML(%s, %s);" %
                   (json.dumps(html), json.dumps(internal)))
Ejemplo n.º 46
0
 def mediatest(self, n):
     return json.loads(
         self.req("mediatest", StringIO(
             json.dumps(dict(n=n)))))
Ejemplo n.º 47
0
 def _drawMark(self):
     self.web.eval("_drawMark(%s);" %
                   json.dumps(self.card.note().hasTag("marked")))
Ejemplo n.º 48
0
 def remove(self, **kw):
     return json.loads(
         self.req("remove", StringIO(json.dumps(kw))))
Ejemplo n.º 49
0
 def mediatest(self, cmd):
     self.postVars = dict(k=self.hkey, )
     return self._dataOnly(
         json.loads(
             self.req("newMediaTest", StringIO(json.dumps(dict(cmd=cmd))))))
Ejemplo n.º 50
0
 def downloadFiles(self, **kw):
     return self.req("downloadFiles", io.BytesIO(json.dumps(kw).encode("utf8")))
Ejemplo n.º 51
0
 def mediaSanity(self, **kw):
     return self._dataOnly(
         json.loads(self.req("mediaSanity", StringIO(json.dumps(kw)))))
Ejemplo n.º 52
0
 def _run(self, cmd, data):
     return json.loads(
         self.req(cmd, io.BytesIO(json.dumps(data).encode("utf8"))).decode("utf8"))
Ejemplo n.º 53
0
 def downloadFiles(self, **kw):
     return self.req("downloadFiles", StringIO(json.dumps(kw)))
Ejemplo n.º 54
0
def hilcd(ed, code, langAlias):
    global LASTUSED
    linenos = gc('linenos')
    centerfragments = gc('centerfragments')
    noclasses = not gc('cssclasses')
    if (ed.mw.app.keyboardModifiers() & Qt.ShiftModifier):
        linenos ^= True
    if (ed.mw.app.keyboardModifiers() & Qt.ControlModifier):
        centerfragments ^= True
    mystyle = gc("style")
    if (ed.mw.app.keyboardModifiers() & Qt.AltModifier):
        d = FilterDialog(parent=None, values=list(get_all_styles()))
        if d.exec():
            mystyle = d.selkey
        noclasses = True
    inline = False
    if (ed.mw.app.keyboardModifiers() & Qt.MetaModifier):
        inline = True
    if inline:
        linenos = False

    try:
        if gc("remove leading spaces if possible", True):
            my_lexer = get_lexer_by_name(langAlias, stripall=False)
        else:
            my_lexer = get_lexer_by_name(langAlias, stripall=True)
    except ClassNotFound as e:
        print(e)
        print(ERR_LEXER)
        showError(ERR_LEXER, parent=ed.parentWindow)
        return False

    try:
        # http://pygments.org/docs/formatters/#HtmlFormatter
        """
nowrap
    If set to True, don’t wrap the tokens at all, not even inside a <pre> tag. This disables most other options (default: False).

full
    Tells the formatter to output a “full” document, i.e. a complete self-contained document (default: False).

title
    If full is true, the title that should be used to caption the document (default: '').

style
    The style to use, can be a string or a Style subclass (default: 'default'). This option has no effect if the cssfile and noclobber_cssfile option are given and the file specified in cssfile exists.

noclasses
    If set to true, token <span> tags (as well as line number elements) will not use CSS classes, but inline styles. This is not recommended for larger pieces of code since it increases output size by quite a bit (default: False).

classprefix
    Since the token types use relatively short class names, they may clash with some of your own class names. In this case you can use the classprefix option to give a string to prepend to all Pygments-generated CSS class names for token types. Note that this option also affects the output of get_style_defs().

cssclass
    CSS class for the wrapping <div> tag (default: 'highlight'). If you set this option, the default selector for get_style_defs() will be this class.
    If you select the 'table' line numbers, the wrapping table will have a CSS class of this string plus 'table', the default is accordingly 'highlighttable'.

cssstyles
    Inline CSS styles for the wrapping <div> tag (default: '').

prestyles
    Inline CSS styles for the <pre> tag (default: '').

cssfile
    If the full option is true and this option is given, it must be the name of an external file. If the filename does not include an absolute path, the file’s path will be assumed to be relative to the main output file’s path, if the latter can be found. The stylesheet is then written to this file instead of the HTML file.

noclobber_cssfile
    If cssfile is given and the specified file exists, the css file will not be overwritten. This allows the use of the full option in combination with a user specified css file. Default is False.

linenos
    If set to 'table', output line numbers as a table with two cells, one containing the line numbers, the other the whole code. This is copy-and-paste-friendly, but may cause alignment problems with some browsers or fonts. If set to 'inline', the line numbers will be integrated in the <pre> tag that contains the code
    The default value is False, which means no line numbers at all.
    For compatibility with Pygments 0.7 and earlier, every true value  except 'inline' means the same as 'table' (in particular, that means also True).

hl_lines
    Specify a list of lines to be highlighted.

linenostart
    The line number for the first line (default: 1).

linenostep
    If set to a number n > 1, only every nth line number is printed.

linenospecial
    If set to a number n > 0, every nth line number is given the CSS class "special" (default: 0).

nobackground
    If set to True, the formatter won’t output the background color for the wrapping element (this automatically defaults to False when there is no wrapping element [eg: no argument for the get_syntax_defs method given]) (default: False).

lineseparator
    This string is output between lines of code. It defaults to "\n", which is enough to break a line inside <pre> tags, but you can e.g. set it to "<br>" to get HTML line breaks.

lineanchors
    If set to a nonempty string, e.g. foo, the formatter will wrap each output line in an anchor tag with a name of foo-linenumber. This allows easy linking to certain lines.

linespans
    If set to a nonempty string, e.g. foo, the formatter will wrap each output line in a span tag with an id of foo-linenumber. This allows easy access to lines via javascript.

anchorlinenos
    If set to True, will wrap line numbers in <a> tags. Used in combination with linenos and lineanchors.

tagsfile
    If set to the path of a ctags file, wrap names in anchor tags that link to their definitions. lineanchors should be used, and the tags file should specify line numbers (see the -n option to ctags).

tagurlformat
    A string formatting pattern used to generate links to ctags definitions. Available variables are %(path)s, %(fname)s and %(fext)s. Defaults to an empty string, resulting in just #prefix-number links.

filename
    A string used to generate a filename when rendering <pre> blocks, for example if displaying source code.

wrapcode
    Wrap the code inside <pre> blocks using <code>, as recommended by the HTML5 specification.
        """
        tablestyling = ""
        if noclasses:
            tablestyling += "text-align: left;"
        if gc("cssclasses") and not gc("css_custom_class_per_style"):
            css_class = "highlight"  # the default for pygments
        else:
            css_class = f"shf__{mystyle}__highlight"
        my_formatter = HtmlFormatter(
            cssclass=css_class,
            cssstyles=tablestyling,
            font_size=16,
            linenos=linenos,
            lineseparator="<br>",
            nobackground=
            False,  # True would solve night mode problem without any config (as long as no line numbers are used)
            noclasses=noclasses,
            style=mystyle,
            wrapcode=True)
    except ClassNotFound as e:
        print(e)
        print(ERR_STYLE)
        showError(ERR_STYLE, parent=ed.parentWindow)
        return False

    pygmntd = highlight(code, my_lexer, my_formatter).rstrip()
    # when using noclasses/inline styling pygments adds line-height 125%, see
    # see https://github.com/pygments/pygments/blob/2fe2152377e317fd215776b6d7467bda3e8cda28/pygments/formatters/html.py#L269
    # It's seems to be only relevant for IE and makes the line numbers misaligned on my PC. So I remove it.
    if noclasses:
        pygmntd = pygmntd.replace('line-height: 125%;', '')
    if inline:
        pretty_code = "".join([pygmntd, "<br>"])
        replacements = {
            '<div class=': '<span class=',
            "<pre": "<code",
            "</pre></div>": "</code></span>",
            "<br>": "",
            "</br>": "",
            "</ br>": "",
            "<br />": "",
            'style="line-height: 125%"': '',
        }
        for k, v in replacements.items():
            pretty_code = pretty_code.replace(k, v)
    else:
        if linenos:
            pretty_code = "".join([pygmntd, "<br>"])
        # to show line numbers pygments uses a table. The background color for the code
        # highlighting is limited to this table
        # If pygments doesn't use linenumbers it doesn't use a table. This means
        # that the background color covers the whole width of the card.
        # I don't like this. I didn't find an easier way than reusing the existing
        # solution.
        # Glutanimate removed the table in the commit
        # https://github.com/glutanimate/syntax-highlighting/commit/afbf5b3792611ecd2207b9975309d05de3610d45
        # which hasn't been published on Ankiweb in 2019-10-02.
        else:
            pretty_code = "".join([
                f'<table class="{css_class}table"><tbody><tr><td>', pygmntd,
                "</td></tr></tbody></table><br>"
            ])
        """
        I can't solely rely on the pygments-HTMLFormatter
        A lot of the stuff I did before 2020-11 with bs4 can indeed be done by adjusting
        the HTMLFormatter options:
        - I can override the ".card {text-align: center}" by using the option "cssstyles"
          (Inline CSS styles for the wrapping <div> tag).
        - I can set a custom class by adjusting the option "cssclass" which defaults to "highlight"
          Besides this there are the classes linenos and linenodiv. BUT I don't need to customize 
          the latter classes. I can also work with longer css rules: 
             /*syntax highlighting fork add-on: dark background*/
             .night_mode .shf__default__highlight{
             background-color: #222222 !important;
             }
             /*syntax highlighting fork add-on: line numbers: white on black: sometimes a span is used, sometimes not*/
             .night_mode .shf__default__highlighttable tr td.linenos div.linenodiv pre span {
             background-color: #222222 !important;
             color: #f0f0f0 !important;
             }
             .night_mode .shf__default__highlighttable tr td.linenos div.linenodiv pre {
             background-color: #222222 !important;
             color: #f0f0f0 !important;
             }
        BUT as far as I see I can't set inline styling for the surrounding table. But to center the
        table I need to add something like "margin: 0 auto;". If you rely on css it's easy because
        the "the wrapping table will have a CSS class of [the cssclass] string plus 'table', the 
        default is accordingly 'highlighttable'.". But my option should work without the user
        adjusting each template and the editor.
        I also need to set the font.
        """
        if centerfragments or (noclasses and gc('font')):
            soup = BeautifulSoup(pretty_code, 'html.parser')
            if centerfragments:
                tablestyling = "margin: 0 auto;"
                for t in soup.findAll("table"):
                    if t.has_attr('style'):
                        t['style'] = tablestyling + t['style']
                    else:
                        t['style'] = tablestyling
            if noclasses and gc('font'):
                for t in soup.findAll("code"):
                    t['style'] = "font-family: %s;" % gc('font')
            pretty_code = str(soup)
    if noclasses:
        out = json.dumps(pretty_code).replace('\n', ' ').replace('\r', '')
        # In 2020-05 I don't remember why I used backticks/template literals
        # here in commit 6ea0fe8 from 2019-11.
        # Maybe for multi-line strings(?) but json.dumps shouldn't include newlines, because
        # json.dumps does "Serialize obj to a JSON formatted str using this conversion table."
        # for the conversion table see https://docs.python.org/3/library/json.html#py-to-json-table
        # which includes JSONEncoder(.. indent=None, separators=None,..) and
        #   If indent ... None (the default) selects the most compact representation.
        # out = "`" + json.dumps(pretty_code)[1:-1] + "`"
        ed.web.eval("MyInsertHtml(%s);" % out)
    else:
        # setFormat is a thin wrapper in Anki around document.execCommand
        ed.web.eval("setFormat('inserthtml', %s);" % json.dumps(pretty_code))
    LASTUSED = langAlias
Ejemplo n.º 55
0
Archivo: sync.py Proyecto: tinnou/anki
 def mediatest(self, cmd):
     self.postVars = dict(k=self.hkey, )
     return self._dataOnly(
         self.req("newMediaTest",
                  io.BytesIO(json.dumps(dict(cmd=cmd)).encode("utf8"))))