Skip to content

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

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>
    <linkhref="http://gmpg.org/xfn/11" rel="profile">
    <metahttp-equiv="X-UA-Compatible" content="IE=edge">
    <metahttp-equiv="content-type" content="text/html; charset=utf-8">
    <metaname="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
    <linkrel="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">
    -->
    <linkrel="stylesheet" href="{{ site.baseurl }}/public/css/monokai.css">
    <linkrel="stylesheet" href="{{ site.baseurl }}/public/css/hyde.css">
    <linkrel="stylesheet" href="{{ site.baseurl }}/public/css/custom.css">
    <linkrel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface">
    <linkrel="apple-touch-icon" sizes="180x180" href="{{ site.baseurl }}/public/apple-touch-icon.png">
    <linkrel="icon" type="image/png" sizes="32x32" href="{{ site.baseurl }}/public/favicon-32x32.png">
    <linkrel="icon" type="image/png" sizes="16x16" href="{{ site.baseurl }}/public/favicon-16x16.png">
    <linkrel="manifest" href="{{ site.baseurl }}/public/site.webmanifest">
    <linkrel="shortcut icon" href="{{ site.baseurl }}/public/favicon.ico">
    <linkrel="alternate" type="application/rss+xml" title="RSS" href="/atom.xml">
    {% if page.canonical_url %}
    <linkrel="canonical" href="{{ page.canonical_url }}" />
    {% endif %}
    {% if page.robots %}
    <metaname="robots" content="{{ page.robots }}">
    {% endif %}
    {% seo %}
    <!-- Global site tag (gtag.js) - Google Analytics -->
    <scriptasyncsrc="https://www.googletagmanager.com/gtag/js?id=UA-52977923-1"></script>
    <script>
    window.dataLayer=window.dataLayer||[];
    functiongtag(){dataLayer.push(arguments);}
    gtag('js',newDate());
    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 */
    .highlightpre {
    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.5rem0;
    border: 0;
    border-top: 1pxsolid#eee;
    border-bottom: 1pxsolid#fff;
    }
    abbr {
    font-size: 85%;
    font-weight: bold;
    color: #555;
    text-transform: uppercase;
    }
    abbr[title] {
    cursor: help;
    border-bottom: 1pxdotted#e5e5e5;
    }
    /* Code */
    code,
    pre {
    font-family: Menlo, Monaco, 'Courier New', monospace;
    }
    code {
    padding: 0.25em0.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;
    }
    precode {
    padding: 0;
    font-size: 100%;
    color: inherit;
    background-color: transparent;
    }
    /* Pygments via Jekyll */
    .highlight {
    margin-bottom: 1rem;
    border-radius: 4px;
    }
    .highlightpre {
    margin-bottom: 0;
    }
    /* Gist via GitHub Pages */
    .gist.gist-file {
    font-family: Menlo, Monaco, 'Courier New', monospace!important;
    }
    .gist.markdown-body {
    padding: 15px;
    }
    .gistpre {
    padding: 0;
    background-color: transparent;
    }
    .gist.gist-file.gist-data {
    font-size: 0.8rem!important;
    line-height: 1.4;
    }
    .gistcode {
    padding: 0;
    color: inherit;
    background-color: transparent;
    border-radius: 0;
    }
    /* Quotes */
    blockquote {
    padding: 0.5rem1rem;
    margin: 0.8rem0;
    color: #7a7a7a;
    border-left: 0.25remsolid#e5e5e5;
    }
    blockquotep:last-child {
    margin-bottom: 0;
    }
    @media (min-width: 30rem) {
    blockquote {
    padding-right: 5rem;
    padding-left: 1.25rem;
    }
    }
    img {
    display: block;
    max-width: 100%;
    margin: 001rem;
    border-radius: 5px;
    }
    /* Tables */
    table {
    margin-bottom: 1rem;
    width: 100%;
    border: 1pxsolid#e5e5e5;
    border-collapse: collapse;
    }
    td,
    th {

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions