Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,5 @@ resources/icons/optional
# Anki
src/*/meta.json
src/*/manifest.json
/meta.json
*~
1 change: 1 addition & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .src.syntax_highlighting import main
1 change: 1 addition & 0 deletions config.json
114 changes: 7 additions & 107 deletions src/syntax_highlighting/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
###############################################################

# Defaults conf
# - we create a new item in mw.col.conf. This syncs the
# - we create a new item in the collection's configuration. This syncs the
# options across machines (but not on mobile)
default_conf = {'linenos': True, # show numbers by default
'centerfragments': True, # Use <center> when generating code fragments
Expand All @@ -52,9 +52,9 @@ def sync_keys(tosync, ref):

def sync_config_with_default(col):
if not 'syntax_highlighting_conf' in col.conf:
col.conf['syntax_highlighting_conf'] = default_conf
col.set_config('syntax_highlighting_conf', default_conf)
else:
sync_keys(col.conf['syntax_highlighting_conf'], default_conf)
sync_keys(col.get_config('syntax_highlighting_conf'), default_conf)

# Mark collection state as modified, else config changes get lost unless
# some unrelated action triggers the flush of collection data to db
Expand All @@ -69,109 +69,9 @@ def setupSyncedConf():

# Local conf

if anki21:
def getConfig():
return mw.addonManager.getConfig(__name__)

def writeConfig(config):
mw.addonManager.writeConfig(__name__, config)

else:
def _addonMeta():
"""Get meta dictionary

Reads in meta.json in add-on folder and returns
resulting dictionary of user-defined metadata values.

Note:
Anki 2.1 stores both add-on meta data and customized
settings in meta.json. In this module we are only dealing
with the settings part.

Returns:
dict: config dictionary

"""

try:
meta = json.load(io.open(meta_path, encoding="utf-8"))
except (IOError, OSError):
meta = None
except json.decoder.JSONDecodeError as e:
print("Could not read meta.json: " + str(e))
meta = None

if not meta:
meta = {"config": _addonConfigDefaults()}
_writeAddonMeta(meta)

return meta

def _writeAddonMeta(meta):
"""Write meta dictionary

Writes meta dictionary to meta.json in add-on folder.

Args:
meta (dict): meta dictionary

"""

with io.open(meta_path, 'w', encoding="utf-8") as f:
f.write(unicode(json.dumps(meta, indent=4,
sort_keys=True,
ensure_ascii=False)))

def _addonConfigDefaults():
"""Get default config dictionary

Reads in config.json in add-on folder and returns
resulting dictionary of default config values.

Returns:
dict: config dictionary

Raises:
Exception: If config.json cannot be parsed correctly.
(The assumption being that we would end up in an
inconsistent state if we were to return an empty
config dictionary. This should never happen.)

"""

try:
return json.load(io.open(defaults_path, encoding="utf-8"))
except (IOError, OSError, json.decoder.JSONDecodeError) as e:
print("Could not read config.json: " + str(e))
raise Exception("Config file could not be read: " + str(e))

def getConfig():
"""Get user config dictionary

Merges user's keys into default config dictionary
and returns the result.

Returns:
dict: config dictionary

"""

config = _addonConfigDefaults()
meta = _addonMeta()
userConf = meta.get("config", {})
config.update(userConf)
return config

def writeConfig(config):
"""Write user config dictionary

Saves user's config dictionary via meta.json.

Args:
config (dict): user config dictionary

"""

_writeAddonMeta({"config": config})
def getConfig():
return mw.addonManager.getConfig(__name__)

def writeConfig(config):
mw.addonManager.writeConfig(__name__, config)
local_conf = getConfig()
45 changes: 9 additions & 36 deletions src/syntax_highlighting/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@

from .config import local_conf

if anki21:
string = str
else:
import string


HOTKEY = local_conf["hotkey"]
STYLE = local_conf["style"]
Expand Down Expand Up @@ -83,7 +78,7 @@ def get_deck_name(mw):


def get_default_lang(mw):
addon_conf = mw.col.conf['syntax_highlighting_conf']
addon_conf = mw.col.get_config('syntax_highlighting_conf')
lang = addon_conf['lang']
if addon_conf['defaultlangperdeck']:
deck_name = get_deck_name(mw)
Expand All @@ -93,7 +88,7 @@ def get_default_lang(mw):


def set_default_lang(mw, lang):
addon_conf = mw.col.conf['syntax_highlighting_conf']
addon_conf = mw.col.get_config('syntax_highlighting_conf')
addon_conf['lang'] = lang # Always update the overall default
if addon_conf['defaultlangperdeck']:
deck_name = get_deck_name(mw)
Expand Down Expand Up @@ -125,7 +120,7 @@ def switch_cssclasses(self):
self.addon_conf['cssclasses'] = not cssclasses_

def setupUi(self):
self.addon_conf = self.mw.col.conf['syntax_highlighting_conf']
self.addon_conf = self.mw.col.get_config('syntax_highlighting_conf')

linenos_label = QLabel('<b>Line numbers</b>')
linenos_checkbox = QCheckBox('')
Expand Down Expand Up @@ -186,9 +181,6 @@ def init_highlighter(ed, *args, **kwargs):
previous_lang = get_default_lang(mw)
ed.codeHighlightLangAlias = LANGUAGES_MAP.get(previous_lang, "")

if not anki21:
addWidgets20(ed, previous_lang)


# Highlighter widgets

Expand Down Expand Up @@ -256,7 +248,7 @@ def add_code_langs_combobox(self, func, previous_lang):
if LIMITED_LANGS:
selection = LIMITED_LANGS
else:
selection = sorted(LANGUAGES_MAP.keys(), key=string.lower)
selection = sorted(LANGUAGES_MAP.keys(), key=str.lower)

for lang in selection:
combo.addItem(lang)
Expand All @@ -270,24 +262,6 @@ def add_code_langs_combobox(self, func, previous_lang):
QSplitter.add_code_langs_combobox = add_code_langs_combobox


def addWidgets20(ed, previous_lang):
# Add the buttons to the Icon Box
splitter = QSplitter()
splitter.add_plugin_button_(ed,
"highlight_code",
lambda _: highlight_code(ed),
key=HOTKEY,
text="",
icon=icon_path,
tip=_("Paste highlighted code ({})".format(HOTKEY)),
check=False)
splitter.add_code_langs_combobox(
lambda lang: onCodeHighlightLangSelect(ed, lang), previous_lang)
splitter.setFrameStyle(QFrame.Plain)
rect = splitter.frameRect()
splitter.setFrameRect(rect.adjusted(10, 0, -10, 0))
ed.iconsBox.addWidget(splitter)


def onCodeHighlightLangSelect(ed, lang):
try:
Expand All @@ -308,7 +282,7 @@ def onCodeHighlightLangSelect(ed, lang):
"""style='vertical-align: top;'>{}</select>""")


def onSetupButtons21(buttons, ed):
def onSetupButtons(buttons, ed):
"""Add buttons to Editor for Anki 2.1.x"""
# no need for a lambda since onBridgeCmd passes current editor instance
# to method anyway (cf. "self._links[cmd](self)")
Expand All @@ -326,7 +300,7 @@ def onSetupButtons21(buttons, ed):
if LIMITED_LANGS:
selection = LIMITED_LANGS
else:
selection = sorted(LANGUAGES_MAP.keys(), key=string.lower)
selection = sorted(LANGUAGES_MAP.keys(), key=str.lower)

options.append(option_str.format(previous_lang))
for lang in selection:
Expand All @@ -349,7 +323,7 @@ def onBridgeCmd(ed, cmd, _old):


def highlight_code(ed):
addon_conf = mw.col.conf['syntax_highlighting_conf']
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
Expand Down Expand Up @@ -433,8 +407,7 @@ def process_html(html):
# Hooks and monkey-patches


if anki21:
addHook("setupEditorButtons", onSetupButtons21)
Editor.onBridgeCmd = wrap(Editor.onBridgeCmd, onBridgeCmd, "around")
addHook("setupEditorButtons", onSetupButtons)
Editor.onBridgeCmd = wrap(Editor.onBridgeCmd, onBridgeCmd, "around")

Editor.__init__ = wrap(Editor.__init__, init_highlighter)