🏆 I provide private lessons on Emacs, Linux, and Life in general: https://protesilaos.com/coach/. Lessons continue throughout the year.

Creating the Prot16 project pages

This post is archived. Opinions expressed herein may no longer represent my current views. Links, images and other media might not work as intended. Information may be out of date. For further questions contact me.

The term “Prot16” refers to my system of colour schemes for highlighting code syntax. As you may have noticed, this website features a section where you can browse through those project pages.1 In this entry, I will document how I went about to design them, by using a combination of SCSS, Liquid logic, and Jekyll data files.

The parameters

Objective

I wanted each page under Prot16 to inherit the project’s colour scheme. When the user visits, say, the Cyprium theme they will be presented with the light variant of Cyprium. When they visit Flowerbed, the website will adapt to Flowerbed’s colours, and so on.

Constraints

I am still not good enough with JavaScript to create an event that would load the respective theme’s stylesheet on click or on page load.

I also did not want to alter my website’s markup, such as to pass an id tag to the body of each page, and then proceed to style it accordingly. Besides, I believe this would require loading all of the colour schemes. That is just too much of an extra burden.

The parts of the process

Setting SCSS defaults

In SCSS we can declare a variable as a default by appending the !default tag. For example:

$red: #C14F4D !default;

What this little addition does is instruct the system to use the given variable only if it is not declared elsewhere, in which case it would use the other one.

We thus proceed to add the !default tag to all the variables that we will later want to override. For the purposes of the Prot16 project, I wanted to alter the following:

  1. the colour scheme
  2. the website’s default colours
  3. the syntax highlighting stylesheet

So here is a snippet:

// Colour scheme

$dbg: #31374D !default;
$dhl: #41475D !default;
$dt2: #81879D !default;
$dt1: #B1B7CD !default;

$lbg: #FCFBFA !default;
$lhl: #ECEBEA !default;
$lt2: #8C8B8A !default;
$lt1: #4C4B4A !default;

$red: #C14F4D !default;
$ora: #DC9316 !default;
$yel: #CEA601 !default;
$gre: #6FA53F !default;

$cya: #55AFCD !default;
$blu: #458FCA !default;
$vio: #AA6ECB !default;
$mag: #CB7EAA !default;

// Site-wide colours

$bg: lighten($lbg, 1.5%) !default;
$bg1: $lbg !default;
$bg2: darken($lbg, 1.5%) !default;
$bhl: $lhl !default;
$text1: $lt1 !default;
$text2: $lt2 !default;
$link: $blu !default;
$linkalt: $gre !default;

I did the same with the parts of the syntax stylesheet that needed to become subject to change.

The Prot16 partial stylesheets

Under _sass I create a themes directory with all the partial stylesheets. Each of them has a set of variables that will take precedence over the aforementioned defaults.

For example, Cyprium includes this:

// Colour scheme

$dbg: #374934; // Dark background
$dhl: #475944; // Dark highlight
$dt2: #879984; // Dark bg text secondary
$dt1: #A7B9A4; // Dark bg text primary

$lbg: #EBE9DA; // Light background
$lhl: #DBD9CA; // Light highlight
$lt2: #9B998A; // Light bg text secondary
$lt1: #6B695A; // Light bg text primary

$red: #C36A5F; // Red
$ora: #B37521; // Orange
$gre: #6B8C4A; // Green
$blu: #3C959A; // Blue

$mag: #BB6384; // Magenta
$yel: #A38E10; // Yellow
$cya: #5C9B85; // Cyan
$vio: #8B85BA; // Violet

// Site-wide colours

$bg: lighten($lbg, 1.5%);
$bg1: $lbg;
$bg2: darken($lbg, 1.5%);
$bhl: $lhl;
$text1: $lt1;
$text2: $lt2;
$link: $ora;
$linkalt: $yel;

These partial stylesheets will eventually be loaded only on the respective project page.

Creating the Prot16 project directory

This is the first time I saw a clear need to use Jekyll’s data files. Under the _data directory I created a themes.yml file. It includes structured information about each Prot16 project, more specifically its proper name and URL slug.

This is how the data file looks:2

- name: Oliveira
  url: "oliveira"
- name: Blau
  url: "blau"
- name: Cyprium
  url: "cyprium"
- name: Nefelio
  url: "nefelio"
- name: Flowerbed
  url: "flowerbed"
- name: Overgrowth
  url: "overgrowth"

The reason why I created this is to call a for loop that checks whether the page in question should load the corresponding Prot16 styles. This will be fully understood in the following subsection.

Loading the project styles

In SCSS it is typical to create partial stylesheets and then import them to the main file. Here is a sample of my main stylesheet prior to the creation of the Prot16 pages.

@import
        "variables",
        "base"
;

I wanted to use Liquid to import a Prot16 stylesheet only on the corresponding project page. I determine the project page by establishing an identity between its permalink and the theme url defined in the aforementioned data file.

This is the loop that does the magic.

{% assign themes = site.data.themes %}

{% for theme in themes %}
  {% if page.permalink contains theme.url %}
    @import "{{ theme.url | prepend: 'themes/' }}";
  {% endif %}
{% endfor %}

What it says is this: if the webpage’s permalink includes the URL slug of a Prot16 project, then load the stylesheet of that project.

To reuse Cyprium as a case in point: if Cyprium’s permalink is /cyprium/ then its URL slug includes cyprium, in which case proceed to load the partial stylesheet cyprium.scss under _sass/themes.

Now the final stylesheet looks like this.

@import
        "variables",
        "base"
;

{% assign themes = site.data.themes %}

{% for theme in themes %}
  {% if page.permalink contains theme.url %}
    @import "{{ theme.url | prepend: 'themes/' }}";
  {% endif %}
{% endfor %}

The end result

Each Prot16 project page works exactly as intended. It uses the colour scheme of the theme under consideration. Plus it only loads the stylesheet it needs. The other Prot16 partials are excluded.

A similar approach is implemented in my new project: the Akademos Jekyll theme.3 I am still developing it, and may therefore change the method, but the idea is to allow the user a simple option to load the partial stylesheet of their favourite Prot16 theme.

I found this exercise to be particularly didactic. Setting SCSS defaults is much more useful than I had first thought. Meanwhile, Jekyll’s data files seem to hold a lot of promise. They provide for a whole range of ways to employ Liquid logic. This ultimately goes to show—yet again—how a static site generator, ostensibly a tool for building simple websites, can handle something rather complex. And I would dare suggest I am only scratching the surface.

  1. For more see the Prot16 section[^]

  2. Note that the url key in the data file does not need to have its value inside quotation marks. I just add it because my text editor gets to highlight it as a string. Makes it easier to scan. [^]

  3. I expect to ship the first proper version of Akademos once Jekyll 3.2 is published. The theme will be distributed as a Ruby gem, so I still need to conduct all sorts of tests. At any rate, I have already set up a demo: https://protesilaos.com/akademos. The demo pages will be updated in the coming days. [^]