CSS Styling
Syntax Highlighting
MdPopups has two syntax highlighting methods: the native Sublime syntax highlighter (default) and Pygments. When developing a plugin, it is wise to test out both. The native Sublime Syntax Highlighter has most default languages mapped along with a few others.
Sublime Syntax Highlighter
As previously mentioned, MdPopups uses the internal syntax highlighter to highlight your code. The benefit here is that you get code highlighting in your popup that matches your current theme. The highlighting ability is dependent upon what syntax packages you have installed in Sublime. It also depends on whether that syntax is enabled and mapped to a language keyword. Pull requests are welcome to expand and keep the language mapping updated. You can also define in your Preferences.sublime-settings
file additional mappings. See mdpopups.sublime_user_lang_map
for more info.
Most users prefer using syntax highlighting that matches their current color scheme. If you are a developer, it is recommended to issue a pull request to add missing languages you need to the mapping. Optionally you can also describe how users can map what they need locally.
Pygments
In order to use Pygments, you have to disable mdpopups.use_sublime_highlighter
. Pygments has a great variety of highlighters out of the box. It also comes with a number of built-in color schemes that can be used. When enabling Pygments, you must specify the color scheme to use in your user CSS using the CSS template filter.
/* Syntax Highlighting */
{%- if var.use_pygments %}
{%- if var.is_light %}
{{'default'|pygments}}
{%- else %}
{{'native'|pygments}}
{%- endif %}
{%- endif %}
You can also paste your own custom Pygments CSS directly into your User CSS, but you will have to format it to work properly.
Pygments defines special classes for each span that needs to be highlighted in a coding block. Pygments CSS classes are not only given syntax classes that are applied to each span, but usually an overall class is assigned to a <div>
wrapper as well. For instance, a class for whitespace may look like this (where .highlight
is the div wrapper's class and .w
i the span's class):
.highlight .w { color: #cccccc } /* Text.Whitespace */
If doing your own, the Pygments CSS should define a rule to highlight general background and foregrounds.
.mdpopups .highlight { background-color: #f8f8f8; color: #4d4d4c }
Full Pygments CSS Example
.mdpopups .highlight { background-color: #f8f8f8; color: #4d4d4c }
.mdpopups .highlight .c { color: #8e908c; font-style: italic } /* Comment */
.mdpopups .highlight .err { color: #c82829 } /* Error */
.mdpopups .highlight .k { color: #8959a8; font-weight: bold } /* Keyword */
.mdpopups .highlight .l { color: #f5871f } /* Literal */
.mdpopups .highlight .n { color: #4d4d4c } /* Name */
.mdpopups .highlight .o { color: #3e999f } /* Operator */
.mdpopups .highlight .p { color: #4d4d4c } /* Punctuation */
.mdpopups .highlight .cm { color: #8e908c; font-style: italic } /* Comment.Multiline */
.mdpopups .highlight .cp { color: #8e908c; font-weight: bold } /* Comment.Preproc */
.mdpopups .highlight .c1 { color: #8e908c; font-style: italic } /* Comment.Single */
.mdpopups .highlight .cs { color: #8e908c; font-style: italic } /* Comment.Special */
.mdpopups .highlight .gd { color: #c82829 } /* Generic.Deleted */
.mdpopups .highlight .ge { font-style: italic } /* Generic.Emph */
.mdpopups .highlight .gh { color: #4d4d4c; font-weight: bold } /* Generic.Heading */
.mdpopups .highlight .gi { color: #718c00 } /* Generic.Inserted */
.mdpopups .highlight .gp { color: #8e908c; font-weight: bold } /* Generic.Prompt */
.mdpopups .highlight .gs { font-weight: bold } /* Generic.Strong */
.mdpopups .highlight .gu { color: #3e999f; font-weight: bold } /* Generic.Subheading */
.mdpopups .highlight .kc { color: #8959a8; font-weight: bold } /* Keyword.Constant */
.mdpopups .highlight .kd { color: #8959a8; font-weight: bold } /* Keyword.Declaration */
.mdpopups .highlight .kn { color: #8959a8; font-weight: bold } /* Keyword.Namespace */
.mdpopups .highlight .kp { color: #8959a8; font-weight: bold } /* Keyword.Pseudo */
.mdpopups .highlight .kr { color: #8959a8; font-weight: bold } /* Keyword.Reserved */
.mdpopups .highlight .kt { color: #eab700; font-weight: bold } /* Keyword.Type */
.mdpopups .highlight .ld { color: #718c00 } /* Literal.Date */
.mdpopups .highlight .m { color: #f5871f } /* Literal.Number */
.mdpopups .highlight .s { color: #718c00 } /* Literal.String */
.mdpopups .highlight .na { color: #4271ae } /* Name.Attribute */
.mdpopups .highlight .nb { color: #4271ae } /* Name.Builtin */
.mdpopups .highlight .nc { color: #c82829; font-weight: bold } /* Name.Class */
.mdpopups .highlight .no { color: #c82829 } /* Name.Constant */
.mdpopups .highlight .nd { color: #3e999f } /* Name.Decorator */
.mdpopups .highlight .ni { color: #4d4d4c } /* Name.Entity */
.mdpopups .highlight .ne { color: #c82829; font-weight: bold } /* Name.Exception */
.mdpopups .highlight .nf { color: #4271ae; font-weight: bold } /* Name.Function */
.mdpopups .highlight .nl { color: #4d4d4c } /* Name.Label */
.mdpopups .highlight .nn { color: #4d4d4c } /* Name.Namespace */
.mdpopups .highlight .nx { color: #4271ae } /* Name.Other */
.mdpopups .highlight .py { color: #4d4d4c } /* Name.Property */
.mdpopups .highlight .nt { color: #c82829 } /* Name.Tag */
.mdpopups .highlight .nv { color: #c82829 } /* Name.Variable */
.mdpopups .highlight .ow { color: #3e999f } /* Operator.Word */
.mdpopups .highlight .w { color: #4d4d4c } /* Text.Whitespace */
.mdpopups .highlight .mb { color: #f5871f } /* Literal.Number.Bin */
.mdpopups .highlight .mf { color: #f5871f } /* Literal.Number.Float */
.mdpopups .highlight .mh { color: #f5871f } /* Literal.Number.Hex */
.mdpopups .highlight .mi { color: #f5871f } /* Literal.Number.Integer */
.mdpopups .highlight .mo { color: #f5871f } /* Literal.Number.Oct */
.mdpopups .highlight .sb { color: #718c00 } /* Literal.String.Backtick */
.mdpopups .highlight .sc { color: #4d4d4c } /* Literal.String.Char */
.mdpopups .highlight .sd { color: #8e908c } /* Literal.String.Doc */
.mdpopups .highlight .s2 { color: #718c00 } /* Literal.String.Double */
.mdpopups .highlight .se { color: #f5871f } /* Literal.String.Escape */
.mdpopups .highlight .sh { color: #718c00 } /* Literal.String.Heredoc */
.mdpopups .highlight .si { color: #f5871f } /* Literal.String.Interpol */
.mdpopups .highlight .sx { color: #718c00 } /* Literal.String.Other */
.mdpopups .highlight .sr { color: #718c00 } /* Literal.String.Regex */
.mdpopups .highlight .s1 { color: #718c00 } /* Literal.String.Single */
.mdpopups .highlight .ss { color: #718c00 } /* Literal.String.Symbol */
.mdpopups .highlight .bp { color: #f5871f } /* Name.Builtin.Pseudo */
.mdpopups .highlight .vc { color: #c82829 } /* Name.Variable.Class */
.mdpopups .highlight .vg { color: #c82829 } /* Name.Variable.Global */
.mdpopups .highlight .vi { color: #c82829 } /* Name.Variable.Instance */
.mdpopups .highlight .il { color: #f5871f } /* Literal.Number.Integer.Long */
CSS Styling
One reason MdPopups was created was to give consistent popups across plugins. Originally MdPopups forced its style so that plugins couldn't override the it. Later it was realized that plugins may have reasons to override certain things, and in recent versions, this constraint was relaxed. Despite changes since its inception, one thing has stayed the same: the user has the last say in how popups work. This is achieved by controlling which CSS gets loaded when.
st=>operation: Sublime CSS/Color Scheme CSS
md=>operation: MdPopups Default CSS
pg=>operation: Plugin CSS
us=>operation: User CSS
st->md->pg->us
Sublime first provides its CSS which includes some basic styling and CSS from color schemes. MdPopups provides its own default CSS that styles the common HTML tags and provides minimal colors. Plugins come next and extend the CSS with plugin specific CSS. The user's CSS is loaded last and can override anything.
All CSS is passed through the Jinja2 template engine where special filters can provide things like appropriate CSS that matches your color scheme for a specific scope, load additional CSS from another source, have condition logic for specific Sublime and/or MdPopups versions, or even provide CSS for specific color schemes.
Templates are used so that a user can easily tap into all the colors, color filters, and other useful logic to control their popups and phantoms in one place without having to hard code a specific CSS for a specific color scheme.
In general, it is encouraged to use Sublime CSS variables such as --redish
, --bluish
, etc. to get appropriate colors for a given theme. Sublime calculates these colors from the color scheme directly. If it calculates a color that is not quite right, you can always request that the color scheme in question redefines that variable with an appropriate color. Or you, as the user, can define one in your user CSS. You can read more about minihtml
and it's features in the minihtml
documentation.
MdPopups also provides its own CSS variables that can be overridden by a user:
Variable | Description |
---|---|
--mdpopups-font-mono | Monospace font stack for elements that require monospace (like code blocks). |
--mdpopups-fg | Foreground color. |
--mdpopups-bg | Background color. |
--mdpopups-link | Hyperlink color. |
--mdpopups-hr | <hr> tag color. |
--mdpopups-admon-fg | General admonition foreground/text color. |
--mdpopups-admon-info-fg | Info admonition foreground/text color. |
--mdpopups-admon-error-fg | Error admonition foreground/text color. |
--mdpopups-admon-success-fg | Success admonition foreground/text color. |
--mdpopups-admon-warning-fg | Warning admonition foreground/text color. |
--mdpopups-admon-title-fg | General admonition title foreground/text color. |
--mdpopups-admon-info-title-fg | Info admonition title foreground/text color. |
--mdpopups-admon-error-title-fg | Error admonition title foreground/text color. |
--mdpopups-admon-success-title-fg | Success admonition title foreground/text color. |
--mdpopups-admon-warning-title-fg | Warning admonition title foreground/text color. |
--mdpopups-admon-bg | General admonition background color. |
--mdpopups-admon-info-bg | Info admonition background color. |
--mdpopups-admon-error-bg | Error admonition background color. |
--mdpopups-admon-warning-bg | Warning admonition background color. |
--mdpopups-admon-success-bg | Success admonition background color. |
--mdpopups-admon-accent | General admonition accent color (border/title bar background). |
--mdpopups-admon-info-accent | Info admonition accent color (border/title bar background). |
--mdpopups-admon-error-accent | Error admonition accent color (border/title bar background). |
--mdpopups-admon-success-accent | Success admonition accent color (border/title bar background). |
--mdpopups-admon-warning-accent | Warning admonition accent color (border/title bar background). |
--mdpopups-kbd-fg | <kbd> foreground/text color. |
--mdpopups-kbd-bg | <kbd> background color. |
--mdpopups-kbd-border | <kbd> border color. |
--mdpopups-hl-border | Inline and block code border color. |
--mdpopups-hl-bg | Inline and block code background color. |
CSS Templates
All variables and filters provided by default only apply to the CSS, not the markdown or HTML content. The default provided variables are namespaced under var
.
The Markdown and HTML content only receives the variables that are given via template_vars
parameters and any options via the template_env_options
; user defined variables will get passed to the CSS, but not the options. User defined variables will be namespaced under plugin
.
CSS Filter
With the template environment, colors and style from the current Sublime color scheme can be accessed and manipulated. Access to the Sublime color scheme styles CSS is done via the css
filter.
css
-
Retrieves the style for a specific Sublime scope from a Sublime color scheme. By specifying either
foreground
,background
, or any scope (complexity doesn't really matter) and feeding it into thecss
filter, all the related styling of the specified scope will be inserted as CSS into the CSS document.Example:
This:
h1, h2, h3, h4, h5, h6 { {{'comment'|css}} }
Might become this:
h1, h2, h3, h4, h5, h6 { color: #888888; font-style: italic; }
Notice that the format of insertion is
key: value;
. You do not need a semicolon after as the CSS lines are all formatted properly with semicolons. If you add one, you may get multiple semicolons which may break the CSS.If you need to get at a specific CSS attribute, you can specify its name in the
css
filter (available attributes arecolor
,background-color
,font-style
, andfont-weight
).This:
h1, h2, h3, h4, h5, h6 { {{'.comment'|css('color')}} }
Would then only include the color:
h1, h2, h3, h4, h5, h6 { color: #888888; }
In general, a foreground color is always returned, but by default, a background color is only returned if one is explicitly defined. To always get a background (which most likely will default to the overall scheme background), you can set the additional
explicit_background
parameter toFalse
./* If `keyword.operator` is not explicitly used, fallback to `.keyword` */ h1, h2, h3, h4, h5, h6 { {{'keyword.operator'|css('color', False)}} }
Color Filters
MdPopups also provides a number of color filters within the template environment that can manipulate the CSS colors returned from the css
filter (or equivalent formatted CSS). These filters will strip out the color and modify it, and return the appropriate CSS. To manipulate a color value directly, you can use Sublime's built in color blending. In most cases, it is advised to use Sublime's color blending functionality, but these are available to aid those who wish to access and manipulate CSS of scopes directly. See Sublime's minihtml
documentation for more info.
Even though Sublime generally provides contrast to popups, lets pretend you had a popup that was the same color as the view window and it was difficult to see where the popup starts and ends. You can take the color schemes background and apply a brightness filter to it allowing you now see the popup clearly.
Here we can make the background of the popup darker:
.mdpopups div.myplugin { {{'.background'|css('background-color')|brightness(0.9)}} }
Color filters take a single color attribute of the form key: value;
. So when feeding the color template filters your CSS via the css
filter, you should specify the color attribute (background-color
or color
) that you wish to apply the filter to; it may be difficult to tell how many attributes css
could return without explicitly specifying attribute. Color filters only take either color
or background-color
attributes.
Filters can be chained if more intensity is needed (as some filters may clamp the value in one call), or if you want to apply multiple filters. These are all the available filters:
foreground
andbackground
-
If desired, you can convert a foreground color to a background color or vice versa. To convert to a foreground color, you can use the
foreground
filter. To convert to a background color, you can use thebackground
filter. Remember, this is augmenting the CSS returned by thecss
filter, you can't just give it a color.To convert a background to a foreground.
Example:
body { {{'.background'|css('background-color')|foreground}} }
To convert a foreground to a background.
Example:
body { {{'.foreground'|css('color')|background}} }
brightness
-
Shifts brightness either dark or lighter. Brightness is relative to
1
where1
means no change. Accepted values are floats that are greater than0
. Ranges are clamped between0
and2
.Example - Darken:
body { {{'.background'|css('background-color')|brightness(0.9)}} }
Example - Lighten:
body { {{'.background'|css('background-color')|brightness(1.1)}} }
contrast
-
Increases/decreases the contrast. Contrast is relative to
1
where1
means no change. Accepted values are floats that are greater than0
. Ranges are clamped between0
and2
.Example - Decrease contrast:
body { {{'.background'|css('background-color')|contrast(0.9)}} }
Example - Increase contrast:
body { {{'.background'|css('background-color')|contrast(1.1)}} }
saturation
-
Shifts the saturation either to right (saturate) or the left (desaturate). Saturation is relative to
1
where1
means no change. Accepted values are floats that are greater than0
. Ranges are clamped between0
and2
.Example - Desaturate:
body { {{'.background'|css('background-color')|saturation(0.9)}} }
Example - Saturate:
body { {{'.background'|css('background-color')|saturation(1.1)}} }
grayscale
-
Filters all colors to a grayish tone.
Example:
body { {{'.background'|css('background-color')|grayscale}} }
sepia
-
Filters all colors to a sepia tone.
Example:
body { {{'.background'|css('background-color')|sepia}} }
invert
-
Inverts a color.
Example:
body { {{'.background'|css('background-color')|invert}} }
colorize
-
Filters all colors to a shade of the specified hue. Think grayscale, but instead of gray, you define a non-gray hue. The values are angular dimensions starting at the red primary at 0°, passing through the green primary at 120° and the blue primary at 240°, and then wrapping back to red at 360°.
Example:
body { {{'.background'|css('background-color')|colorize(30)}} }
hue
-
Shifts the current hue either to the left or right. The values are angular dimensions starting at the red primary at 0°, passing through the green primary at 120° and the blue primary at 240°, and then wrapping back to red at 360°. Values can either be negative to shift left or positive to shift the hue to the right.
Example - Left Shift:
body { {{'.background'|css('background-color')|hue(-30)}} }
Example - Left Right:
body { {{'.background'|css('background-color')|hue(30)}} }
fade
-
Fades a color. Essentially it is like apply transparency to the color allowing the color schemes base background color to show through.
Example - Fade 50%:
body { {{'.foreground'|css('color')|fade(0.5)}} }
Include CSS Filter
The template environment allows for retrieving CSS resources from Sublime Packages or built-in Pygments CSS from the Pygments library.
getcss
-
Retrieve a CSS file from Sublime's
Packages
folder. CSS retrieved in this manner can include template variables and filters.Example:
{{'Packages/User/aprosopo-dark.css'|getcss}}
pygments
-
Retrieve a built-in Pygments color scheme.
Example:
{{'native'|pygments}}
Template Variables
The template environment provides a couple of variables that can be used to conditionally alter the CSS output. Variables are found under var
.
var.sublime_version
-
sublime_version
contains the current Sublime Text version. This allows you conditionally handle CSS features that are specific to a Sublime Text version.Example
{% if var.sublime_version >= 3119 %} padding: 0.2rem; {% else %} padding: 0.2em; {% endif %}
var.mdpopups_version
-
mdpopups_version
contains the current MdPopups version which you can use in your CSS templates if needed.Example
{% if var.mdpopups_version >= (1, 9, 0) %} /* do something */ {% else %} /* do something else */ {% endif %}
var.default_style
- Flag specifying whether default styling is being used. See
mdpopups.default_style
for how to control this flag. And seedefault.css
for an example of how it is used. var.is_dark
andvar.is_light
-
is_dark
checks if the color scheme is a dark color scheme. Alternatively,is_light
checks if the color scheme is a light color scheme.Example:
{% if var.is_light %} html{ {{'.background'|css('background-color')|brightness(0.9)}} } {% else %} html{ {{'.background'|css('background-color')|brightness(1.1)}} } {% endif %}
var.is_popup
,var.is_phantom
, andvar.is_sheet
-
is_phantom
checks if the current CSS is for a phantom instead of a popup. Alternatively,is_popup
andis_sheet
checks if the current use of the CSS is for a popup or HTML sheet respectively.Example:
{% if var.is_phantom %} html{ {{'.background'|css('background-color')|brightness(0.9)}} } {% else %} html{ {{'.background'|css('background-color')|brightness(1.1)}} } {% endif %}
var.use_pygments
-
Checks if the Pygments syntax highlighter is being used.
Example:
{% if var.use_pygments %} {% if var.is_light %} {{'default'|pygments}} {% else %} {{'native'|pygments}} {% endif %} {% endif %}
var.color_scheme
-
Retrieves the current color schemes name.
Example:
{% if ( var.color_scheme in ( 'Packages/Theme - Aprosopo/Tomorrow-Night-Eighties-Stormy.tmTheme', 'Packages/Theme - Aprosopo/Tomorrow-Morning.tmTheme', ) ) %} a { {{'.keyword.operator'|css('color')}} } {% else %} a { {{'.support.function'|css('color')}} } {% endif %}