Skip to content

Up-to-date syntax theme for Atom that matches GitHub's motif, including day/night mode.

License

Notifications You must be signed in to change notification settings

Alhadis/Atom-GitHubSyntax

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GitHub syntax theme for Atom

This is a syntax highlighting theme for Atom that replicates the exact appearance of highlighted source-code on GitHub.com. It was created to facilitate development of TextMate-compatible grammars for use on GitHub.

Comparison between syntax theme and GitHub's styling (as of 2022-02-26)

Features

  • Automatic dark-mode detected from system settings.
  • Support for high-contrast and “dimmed” theme variants.
  • Support for colourblind users (protanopia, deuteranopia, tritanopia)
  • Pathologically-accurate highlighting (see next section)
  • Automated styling updates; run tools/update-styles.sh to update CSS.

To-do list

  • Setup continuous integration
  • Write up contributor docs
  • Add setting to enable manual dark/light-mode selection
  • Investigate supporting ChromeDriver for headless updates

TextMate vs CSS

TextMate Scope Selectors are not completely compatible with CSS classes, despite sharing a superficial resemblance:

.string.quoted.double      CSS
 string.quoted.double      TextMate

In CSS, the order in which classes are listed in a class selector is irrelevant: .string.quoted.double is behaves the same as .double.quoted.string. TextMate selectors, however, are sensitive to the order in which scopes are listed, which means string.quoted matches string.quoted.double but not quoted.string, string.foo.quoted, or even foo.string.quoted.

Why is this relevant?

GitHub uses TextMate selectors to map tokenised scope-lists onto CSS classes. In rare cases, a grammar might specify a scope-list that TextMate and CSS selectors interpret differently. For example, consider the following pattern:

name: "variable.global.other"
match: /\$\w+/

GitHub recognises both the variable and variable.other scopes, and assigns a different colour to each. On GitHub, the aforementioned rule will be highlighted as the former (variable), whereas a naïve theme targeting .variable.other in CSS will see the latter.

The solution

CSS provides no elegant way to implement an “order-dependent class selector”. An ugly alternative is to use attribute selectors instead:

// NB: This example omits the rebarbative `syntax--` prefix necessitated by Atom
:is([class="string quoted double"], [class^="string quoted double "]){
	
}

Astute authors will correctly note several limitations with this approach:

  1. Classes must be separated by a single space (U+0020) only.
    Multiple spaces or other whitespace characters won't match.
  2. class attributes cannot contain leading or trailing whitespace.
  3. Selectors must avoid matching more qualified scope-lists.
    E.g., variable.other should not inherit the styling applied to variable, or vice versa. This requires the inclusion of a :not() qualifier for every conflicting scope-list. For example:
    // Target "string" scope, but not more qualified selectors
    // such as "string.quoted.double" or "string.quoted.single"
    :is([class^="string "]):not(
    	[class^="string quoted double"],
    	[class^="string quoted single"]
    ){ }
  4. The list of supported scopes must be known ahead-of-time.
    This is stipulated by the previous point.

Thankfully, each constraint is satisfied by Atom's built-in use of Less for generating stylesheets. A script is provided for regenerating the scope-map variables listed in scope-map.less.

Related links