Skip to content

Make code fence syntax highlighting consistent and GitHub-like (replace monokai with Rouge GitHub CSS) #7

@solrevdev

Description

@solrevdev

Summary
Some fenced code (notably bash) renders poorly compared to others (e.g., powershell). We currently use kramdown + Rouge for highlighting, but our CSS stack mixes a dark monokai palette with light “Poole/Hyde” base styles, causing low-contrast or inconsistent coloring.

Current setup (confirmed)

  • _config.yml:
    • highlighter: rouge
    • markdown: kramdown
    • theme: jekyll-theme-cayman
  • _includes/head.html loads:
    • /public/css/poole.css
    • /public/css/monokai.css ← active dark syntax theme
    • /public/css/hyde.css
    • /public/css/custom.css
  • public/css/custom.scss:
    • Adds syntax for keyboard keys aka kbd
    • Adds scrollability to Rouge code:
      .highlight pre { white-space: pre; overflow-x: auto; word-break: inherit; word-wrap: inherit; }
  • public/css/poole.scss:
    • Sets pre background: #f9f9f9 (light), fonts, spacing
    • Defines .highlight container (no color palette)

Hypothesis

  • monokai.css (dark) + Poole pre (light) = color contrast mismatches for some lexers (bash). Powershell looks “okay” by chance under this mix, leading to inconsistent results.

Goals

  • Consistent, readable highlighting for all fenced code (bash/sh/zsh, yaml, json, ps1, js/ts, ruby, python, go, etc.).
  • Use a GitHub-like palette that matches our light background without adding JS.

Proposed solution (Option A – Rouge GitHub theme)

  1. Generate a Rouge GitHub CSS file locally:
    • gem install rouge
    • rougify style github > public/css/syntax.css
    • (Alternatives: github-dark, github-dark-dimmed if we want dark mode later.)
  2. Swap monokai.css for the new syntax.css in _includes/head.html:
    • Remove/disable:
    • Add:
  3. Keep the existing scrollability rules in public/css/custom.scss:
    • .highlight pre { white-space: pre; overflow-x: auto; word-break: inherit; word-wrap: inherit; }
  4. Optional: ensure consistent light background if needed (matches GitHub light):
    • In custom.scss (or syntax.css if preferred), we can assert:
      .highlight, .highlight pre { background-color: #f6f8fa; color: #24292e; }
    • This prevents pre { background-color: #f9f9f9; } from fighting the theme and keeps colors uniform.

Acceptance criteria

  • All fenced code blocks render with a consistent, GitHub-like palette on a light background.
  • No need to mislabel code blocks (e.g., bash as powershell).
  • Existing layout/typography unaffected; code blocks retain horizontal scrolling.
  • Tested with bash/sh, powershell, yaml, json, js/ts, ruby, python, go samples.

Notes/alternatives

  • If we prefer a dark scheme, use rougify style github-dark and then set a dark background for .highlight/.highlight pre to match, or remove Poole’s light pre background for code blocks in that context.
  • We intentionally avoid client-side highlighters (highlight.js/Prism) to keep builds simple and fast.

References to current code (for reviewers)

  • _config.yml (Rouge/kramdown):
    # Plugins
    plugins:
    - github-pages
    - jekyll-paginate
    - jekyll-sitemap
    - jekyll-feed
    - jekyll-github-metadata
    - jemoji
    - jekyll-seo-tag
    - jekyll-loading-lazy
    # Dependencies
    highlighter: rouge
    markdown: kramdown
    # Permalinks
    # excerpt_separator: ''
    # Setup
    title: "solrevdev tech radar"
    short_title: "solrevdev"
    tagline: "A blog about things I find on the web, tools and technologies that I like."
    description: "solrevdev is a blog by the software engineer John Smith about things he finds on the web, tools and technologies that he likes."
    url: "https://solrevdev.com"
    baseurl: ""
    # Minify css
    sass:
    style: compressed
    # Contacts
    author:
    name: "John Smith"
    url: "https://solrevdev.com/about/"
    email: "john@solrevdev.com"
    github: "https://github.com/solrevdev"
    facebook: "https://www.facebook.com/solrevdevtechradar"
    instagram: "https://www.instagram.com/solrevdev"
    twitter: "https://www.twitter.com/solrevdev"
    # Outputting
    paginate: 5
    # Custom vars
    version: "2.1.0"
    github: [metadata]
    exclude: ["Rakefile", "vendor"]
    # Social Sharing
    facebook_app_id: "1213637668669023"
    theme: jekyll-theme-cayman
    prose:
    siteurl: "https://solrevdev.com"
    media: "media"
  • _includes/head.html (CSS includes and monokai.css):
    <head>
    <link href="http://gmpg.org/xfn/11" rel="profile">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
    <link rel="stylesheet" href="{{ site.baseurl }}/public/css/poole.css">
    <!--
    replace existing syntax css for a nice dark theme
    https://jwarby.github.io/jekyll-pygments-themes/languages/java.html
    https: //raw.githubusercontent.com/jwarby/pygments-css/master/monokai.css
    <link rel="stylesheet" href="{{ site.baseurl }}/public/css/syntax.css">
    -->
    <link rel="stylesheet" href="{{ site.baseurl }}/public/css/monokai.css">
    <link rel="stylesheet" href="{{ site.baseurl }}/public/css/hyde.css">
    <link rel="stylesheet" href="{{ site.baseurl }}/public/css/custom.css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface">
    <link rel="apple-touch-icon" sizes="180x180" href="{{ site.baseurl }}/public/apple-touch-icon.png">
    <link rel="icon" type="image/png" sizes="32x32" href="{{ site.baseurl }}/public/favicon-32x32.png">
    <link rel="icon" type="image/png" sizes="16x16" href="{{ site.baseurl }}/public/favicon-16x16.png">
    <link rel="manifest" href="{{ site.baseurl }}/public/site.webmanifest">
    <link rel="shortcut icon" href="{{ site.baseurl }}/public/favicon.ico">
    <link rel="alternate" type="application/rss+xml" title="RSS" href="/atom.xml">
    {% if page.canonical_url %}
    <link rel="canonical" href="{{ page.canonical_url }}" />
    {% endif %}
    {% if page.robots %}
    <meta name="robots" content="{{ page.robots }}">
    {% endif %}
    {% seo %}
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-52977923-1"></script>
    <script>
    window.dataLayer = window.dataLayer || [];
    function gtag() { dataLayer.push(arguments); }
    gtag('js', new Date());
    gtag('set', 'hostname', 'solrevdev.com');
    gtag('set', 'linker', { 'domains': ['solrevdev.com'] });
    gtag('config', 'UA-52977923-1');
    </script>
    </head>
  • public/css/custom.scss (scrollable code):
    ---
    ---
    /* custom css for keyboard shortcuts */
    kbd {
    border-style: outset;
    border-width: 2px;
    border-color: #999999;
    border-radius: 6px;
    padding: 3px;
    font-size: 75%;
    font-weight: 475;
    background-color: #f8f8f8;
    margin: 2px;
    white-space: nowrap;
    }
    /* custom css for rouge highlighter code syntax - add scroll bars etc */
    .highlight pre {
    white-space: pre;
    overflow-x: auto;
    word-break: inherit;
    word-wrap: inherit;
    }
  • public/css/poole.scss (base code styles):
    }
    h4,
    h5,
    h6 {
    margin-top: 1rem;
    font-size: 1rem;
    }
    /* Body text */
    p {
    margin-top: 0;
    margin-bottom: 1rem;
    }
    strong {
    color: #303030;
    }
    /* Lists */
    ul,
    ol,
    dl {
    margin-top: 0;
    margin-bottom: 1rem;
    }
    dt {
    font-weight: bold;
    }
    dd {
    margin-bottom: 0.5rem;
    }
    /* Misc */
    hr {
    position: relative;
    margin: 1.5rem 0;
    border: 0;
    border-top: 1px solid #eee;
    border-bottom: 1px solid #fff;
    }
    abbr {
    font-size: 85%;
    font-weight: bold;
    color: #555;
    text-transform: uppercase;
    }
    abbr[title] {
    cursor: help;
    border-bottom: 1px dotted #e5e5e5;
    }
    /* Code */
    code,
    pre {
    font-family: Menlo, Monaco, 'Courier New', monospace;
    }
    code {
    padding: 0.25em 0.5em;
    font-size: 85%;
    color: #bf616a;
    background-color: #f9f9f9;
    border-radius: 3px;
    }
    pre {
    display: block;
    margin-top: 0;
    margin-bottom: 1rem;
    padding: 1rem;
    font-size: 0.8rem;
    line-height: 1.4;
    white-space: pre;
    white-space: pre-wrap;
    word-break: break-all;
    word-wrap: break-word;
    background-color: #f9f9f9;
    }
    pre code {
    padding: 0;
    font-size: 100%;
    color: inherit;
    background-color: transparent;
    }
    /* Pygments via Jekyll */
    .highlight {
    margin-bottom: 1rem;
    border-radius: 4px;
    }
    .highlight pre {
    margin-bottom: 0;
    }
    /* Gist via GitHub Pages */
    .gist .gist-file {
    font-family: Menlo, Monaco, 'Courier New', monospace !important;
    }
    .gist .markdown-body {
    padding: 15px;
    }
    .gist pre {
    padding: 0;
    background-color: transparent;
    }
    .gist .gist-file .gist-data {
    font-size: 0.8rem !important;
    line-height: 1.4;
    }
    .gist code {
    padding: 0;
    color: inherit;
    background-color: transparent;
    border-radius: 0;
    }
    /* Quotes */
    blockquote {
    padding: 0.5rem 1rem;
    margin: 0.8rem 0;
    color: #7a7a7a;
    border-left: 0.25rem solid #e5e5e5;
    }
    blockquote p:last-child {
    margin-bottom: 0;
    }
    @media (min-width: 30rem) {
    blockquote {
    padding-right: 5rem;
    padding-left: 1.25rem;
    }
    }
    img {
    display: block;
    max-width: 100%;
    margin: 0 0 1rem;
    border-radius: 5px;
    }
    /* Tables */
    table {
    margin-bottom: 1rem;
    width: 100%;
    border: 1px solid #e5e5e5;
    border-collapse: collapse;
    }
    td,
    th {

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions