From c9f65189c4257dce6b3cf072dfc6170584552981 Mon Sep 17 00:00:00 2001 From: Timothy Rae Date: Sat, 26 Dec 2015 22:38:58 +0900 Subject: [PATCH] Add option to enable CSS classes In order to use syntax highlighting with night mode in AnkiDroid, it's highly desirable to use CSS classes instead of directly including the formatting in the html. This commit adds a setting to do that, and also adds a little bit of documentation on how to use it. --- code_highlight_addon/code_highlight_addon.py | 34 ++++++-- code_highlight_addon/docs.txt | 88 +++++++++++++++++++- 2 files changed, 113 insertions(+), 9 deletions(-) diff --git a/code_highlight_addon/code_highlight_addon.py b/code_highlight_addon/code_highlight_addon.py index 54a502d..306fd53 100644 --- a/code_highlight_addon/code_highlight_addon.py +++ b/code_highlight_addon/code_highlight_addon.py @@ -99,6 +99,7 @@ def add_code_langs_combobox(self, func, previous_lang): #### options across machines (but not on mobile) default_conf = {'linenos': True, # show numbers by default 'centerfragments': True, # Use
when generating code fragments + 'cssclasses': False, # Use css classes instead of colors directly in html 'defaultlangperdeck': True, # Default to last used language per deck 'deckdefaultlang': {}, # Map to store the default language per deck 'lang': 'Python'} # default language is Python @@ -157,7 +158,7 @@ def __init__(self, mw): def switch_linenos(self): linenos_ = self.addon_conf['linenos'] self.addon_conf['linenos'] = not linenos_ - + def switch_centerfragments(self): centerfragments_ = self.addon_conf['centerfragments'] self.addon_conf['centerfragments'] = not centerfragments_ @@ -166,6 +167,10 @@ def switch_defaultlangperdeck(self): defaultlangperdeck_ = self.addon_conf['defaultlangperdeck'] self.addon_conf['defaultlangperdeck'] = not defaultlangperdeck_ + def switch_cssclasses(self): + cssclasses_ = self.addon_conf['cssclasses'] + self.addon_conf['cssclasses'] = not cssclasses_ + def setupUi(self): # If config options have changed, sync with default config first sync_config_with_default(self.mw.col) @@ -181,20 +186,28 @@ def setupUi(self): center_checkbox = QCheckBox('') center_checkbox.setChecked(self.addon_conf['centerfragments']) center_checkbox.stateChanged.connect(self.switch_centerfragments) - + + cssclasses_label = QLabel('Use CSS classes') + cssclasses_checkbox = QCheckBox('') + cssclasses_checkbox.setChecked(self.addon_conf['cssclasses']) + cssclasses_checkbox.stateChanged.connect(self.switch_cssclasses) + defaultlangperdeck_label = QLabel('Default to last language used per deck') defaultlangperdeck_checkbox = QCheckBox('') defaultlangperdeck_checkbox.setChecked(self.addon_conf['defaultlangperdeck']) defaultlangperdeck_checkbox.stateChanged.connect(self.switch_defaultlangperdeck) - + + grid = QGridLayout() grid.setSpacing(10) grid.addWidget(linenos_label, 0, 0) grid.addWidget(linenos_checkbox, 0, 1) grid.addWidget(center_label, 1, 0) grid.addWidget(center_checkbox, 1, 1) - grid.addWidget(defaultlangperdeck_label, 2, 0) - grid.addWidget(defaultlangperdeck_checkbox, 2, 1) + grid.addWidget(cssclasses_label, 2, 0) + grid.addWidget(cssclasses_checkbox, 2, 1) + grid.addWidget(defaultlangperdeck_label, 3, 0) + grid.addWidget(defaultlangperdeck_checkbox, 3, 1) self.setLayout(grid) @@ -291,6 +304,12 @@ def highlight_code(self): 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 = self.web.selectedText() if selected_text: # Sometimes, self.web.selectedText() contains the unicode character @@ -307,10 +326,9 @@ def highlight_code(self): # 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) + # Create html formatter object including flags for line nums and css classes + my_formatter = HtmlFormatter(linenos=linenos, noclasses=noclasses, font_size=16) if linenos: if centerfragments: pretty_code = "".join(["
", diff --git a/code_highlight_addon/docs.txt b/code_highlight_addon/docs.txt index 1524021..4044b8d 100644 --- a/code_highlight_addon/docs.txt +++ b/code_highlight_addon/docs.txt @@ -1,4 +1,5 @@ NEW: +- added option to use css classes (disabled by default) - you can now toggle line numbers on or off in the source code - some small changes have been made. Everyone should upgrade @@ -27,9 +28,94 @@ Configuration ----------------- You can choose whether or not to display line numbers in the highlighted source code. -Just go to Tools > Syntax Highlighting (options). A new window will appear. +Just go to Tools > Syntax Highlighting (options). +A new window will appear. Toggle the check box on or off to display or hide the line numbers. +You can also choose whether to include the styling directly in the text html (default) or to use css classes. +Using css classes allows you more customization, and results in a smaller database size, but you'll need to manually include a styling sheet in every note type, so it's only recommended for advanced users. Here is some default css code to include in your templates: + +```css +.highlight { + text-align:left; + font-family: droid sans mono; + background-color: #f2f2f2; + padding-left: 5px; + padding-right: 5px; +} + +.night_mode .highlight { + /* Invert all of the colors when using night mode in AnkiDroid */ + color:black; + background-color: #C2C2C2; + filter: invert(1); -webkit-filter:invert(1); +} + +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #408080; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #008000; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #BC7A00 } /* Comment.Preproc */ +.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #808080 } /* Generic.Output */ +.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0040D0 } /* Generic.Traceback */ +.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #008000 } /* Keyword.Pseudo */ +.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #B00040 } /* Keyword.Type */ +.highlight .m { color: #666666 } /* Literal.Number */ +.highlight .s { color: #BA2121 } /* Literal.String */ +.highlight .na { color: #7D9029 } /* Name.Attribute */ +.highlight .nb { color: #008000 } /* Name.Builtin */ +.highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +.highlight .no { color: #880000 } /* Name.Constant */ +.highlight .nd { color: #AA22FF } /* Name.Decorator */ +.highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #0000FF } /* Name.Function */ +.highlight .nl { color: #A0A000 } /* Name.Label */ +.highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #19177C } /* Name.Variable */ +.highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #666666 } /* Literal.Number.Float */ +.highlight .mh { color: #666666 } /* Literal.Number.Hex */ +.highlight .mi { color: #666666 } /* Literal.Number.Integer */ +.highlight .mo { color: #666666 } /* Literal.Number.Oct */ +.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */ +.highlight .sc { color: #BA2121 } /* Literal.String.Char */ +.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #BA2121 } /* Literal.String.Double */ +.highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */ +.highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +.highlight .sx { color: #008000 } /* Literal.String.Other */ +.highlight .sr { color: #BB6688 } /* Literal.String.Regex */ +.highlight .s1 { color: #BA2121 } /* Literal.String.Single */ +.highlight .ss { color: #19177C } /* Literal.String.Symbol */ +.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #19177C } /* Name.Variable.Class */ +.highlight .vg { color: #19177C } /* Name.Variable.Global */ +.highlight .vi { color: #19177C } /* Name.Variable.Instance */ +.highlight .il { color: #666666 } /* Literal.Number.Integer.Long */ +``` + + Pygments ------------- All syntax highlighting is handled by the python package Pygments.