Project

ohhighmark

0.0
No release in over 3 years
OhHighMark is a Ruby library for syntax highlighting of markdown code, providing colorful and readable markdown syntax visualization.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
 Dependencies

Development

~> 3.12
 Project Readme

OhHighMark 👋

A Ruby library for syntax highlighting markdown code with beautiful, customizable output.

OhHighMark provides colorful and readable markdown syntax visualization by tokenizing and rendering markdown with appropriate CSS classes. It displays each line in a table row with line numbers, ensuring perfect alignment and preserving all whitespace.

Overview

Key Features

  • Table-based layout - Each line in its own table row with separate cells for line numbers and code
  • Perfect alignment - Line numbers stay aligned with code content, even with long lines
  • Whitespace preservation - Uses white-space: pre to maintain exact spacing and indentation
  • Non-selectable line numbers - Prevents copy/paste issues
  • Comprehensive markdown support - Headings, text formatting, code, links, lists, tables, quotes, and more
  • Inline markdown in lists - Bold, italic, links, and other inline syntax work within list items
  • Customizable styling - Pre-built CSS with CSS variables for easy theming
  • Semantic HTML - Clean, semantic markup with data-line-number on rows
  • Flexible rules - Customizable tokenization rules via DSL

Supported Markdown Syntax

OhHighMark supports all standard markdown elements:

Text Formatting:

  • Bold: **text**
  • Italic: _text_
  • Bold-Italic: ***text***
  • Strikethrough: ~~text~~

Headings: # H1 through ###### H6

Code:

  • Inline: `code`
  • Fenced blocks: ``` ... ```

Links:

  • Standard: [text](url)
  • Auto-links: <http://url>

Lists:

  • Unordered: - item, * item, + item
  • Nested: - nested item
  • With inline markdown: - **bold** with [link](url)

Tables:

| Column 1 | Column 2 |
| -------- | -------- |
| Value 1  | Value 2  |

Other:

  • Horizontal rules: ---
  • Block quotes: > quote
  • Escaped characters: \*, \[, \], \\

Installation

Add to your Gemfile:

gem 'ohhighmark'

Then run:

$ bundle install

Or install directly:

$ gem install ohhighmark

Usage

Basic Usage

require 'ohhighmark'

# Use the helper in your views (Rails, Middleman, etc.)
include OhHighMark::Helper

# In your ERB view:
<%= highlight_markdown do %>
  # Your Markdown Here
  
  This is **bold** and this is _italic_.
  
  - List item with [link](https://example.com)
  - Item with `inline code`
<% end %>

Direct API Usage

require 'ohhighmark'

markdown = <<~MD
  # Welcome
  
  This is **bold** and ~~strikethrough~~.
MD

# Create highlighter and process
highlighter = OhHighMark::Highlighter.new
html_output = highlighter.process_lines_with_linenums(markdown)

Advanced: Custom Rules

# Define custom markdown rules
ruleset = OhHighMark::RuleSet.new
OhHighMark::MarkdownRules.apply(ruleset)

# Add custom rules if needed
ruleset.add(:custom_pattern, /your_regex/, :inline)

# Create tokenizer and renderer
tokenizer = OhHighMark::Tokenizer.new(ruleset.rules)
tokens = tokenizer.tokenize(markdown_text)

renderer = OhHighMark::Renderer.new
html = renderer.render(tokens)

Styling

OhHighMark includes a pre-built CSS stylesheet with CSS custom properties (CSS variables) for easy customization.

Including the Stylesheet

Rails (Asset Pipeline / Sprockets):

In application.css:

/*
 *= require ohhighmark/ohhighmark
 */

Or in application.scss:

@import 'ohhighmark/ohhighmark';

Rails (Propshaft / Importmap):

Copy the stylesheet:

$ cp $(bundle show ohhighmark)/app/assets/stylesheets/ohhighmark/ohhighmark.css app/assets/stylesheets/

Link in your layout:

<%= stylesheet_link_tag "ohhighmark" %>

Middleman:

Copy the stylesheet:

$ cp $(bundle show ohhighmark)/app/assets/stylesheets/ohhighmark/ohhighmark.css source/stylesheets/

Then import it in your main stylesheet.

Standalone / Other Frameworks:

Find the stylesheet in the gem:

$ bundle show ohhighmark
# Copy app/assets/stylesheets/ohhighmark/ohhighmark.css to your project

Customizing Colors

Override CSS variables after including the OhHighMark stylesheet:

:root {
  /* Text and background */
  --ohm-text-color: #ffffff;
  --ohm-background-color: #1a1a1a;
  --ohm-linenos-color: #666666;
  --ohm-linenos-bg-color: #1a1a1a;
  
  /* Syntax colors */
  --ohm-yellow: #ffff00;        /* H1 headings */
  --ohm-orange: #ff8000;        /* H2 headings */
  --ohm-purple: #ff00ff;        /* H3 headings */
  --ohm-cyan: #00ffff;          /* H4-H6 headings */
  --ohm-blue: #0080ff;          /* Links */
  --ohm-intense-blue: #0040ff;  /* Link hover */
  --ohm-green: #00ff00;         /* Quotes, lists */
  --ohm-gray: #808080;          /* Horizontal rules */
  --ohm-grayish: #999999;       /* Table borders */
  
  /* Table highlighting */
  --ohm-table-bg: rgba(255, 248, 197, 0.2);
  
  /* Font */
  --ohm-monospace-font: "Courier New", monospace;
}

Dark Theme Example:

:root {
  --ohm-text-color: #e0e0e0;
  --ohm-background-color: #0d1117;
  --ohm-linenos-bg-color: #0d1117;
  --ohm-linenos-color: #6e7681;
  --ohm-blue: #4a9eff;
  --ohm-green: #7cfc00;
  --ohm-yellow: #ffd700;
  --ohm-orange: #ff6b35;
}

Light Theme Example:

:root {
  --ohm-text-color: #333333;
  --ohm-background-color: #ffffff;
  --ohm-linenos-bg-color: #f6f8fa;
  --ohm-linenos-color: #57606a;
  --ohm-blue: #0969da;
  --ohm-green: #1a7f37;
  --ohm-yellow: #b8860b;
  --ohm-orange: #d2691e;
}

HTML Structure

OhHighMark generates semantic HTML with clean structure:

<div class="ohhighmark">
  <table class="highlight">
    <tbody>
      <!-- Regular content row -->
      <tr data-line-number="1">
        <td class="blob-num">1</td>
        <td class="blob-code"><span class="md-h1"># Heading</span></td>
      </tr>
      
      <!-- Row with text -->
      <tr data-line-number="2">
        <td class="blob-num">2</td>
        <td class="blob-code">Some text with <span class="md-bold">**bold**</span></td>
      </tr>
      
      <!-- Table row (has table-line class) -->
      <tr class="table-line" data-line-number="3">
        <td class="blob-num">3</td>
        <td class="blob-code"><span class="md-table-pipe">|</span> Col 1 <span class="md-table-pipe">|</span> Col 2 <span class="md-table-pipe">|</span></td>
      </tr>
    </tbody>
  </table>
</div>

Key Structure Points:

  • data-line-number attribute on <tr> for easy row targeting
  • .blob-num cell contains line number
  • .blob-code cell contains formatted content
  • .table-line class added to rows that are part of markdown tables
  • Markdown syntax wrapped in <span> elements with .md-* classes

CSS Classes Reference

Container & Layout:

  • .ohhighmark - Main container div
  • table.highlight - Table element containing all lines
  • .blob-num - Line number cell (user-select: none prevents copying)
  • .blob-code - Code content cell (uses white-space: pre)
  • .table-line - Added to <tr> for markdown table rows

Markdown Syntax Classes:

  • .md-h1 through .md-h6 - Heading levels 1-6
  • .md-bold - Bold text (**text**)
  • .md-italic - Italic text (_text_)
  • .md-em - Bold-italic emphasis (***text***)
  • .md-strikethrough - Strikethrough (~~text~~)
  • .md-code - Inline code (`code`)
  • .md-link - Standard links ([text](url))
  • .md-autolink - Auto-linked URLs (<http://url>)
  • .md-li - List item markers
  • .md-hr - Horizontal rules (---)
  • .md-fence - Fenced code block delimiters
  • .md-codeblock - Content within fenced code blocks
  • .md-table-pipe - Table pipe characters (|)
  • .md-table-dash - Table separator rows (---)
  • .md-quote - Block quotes (> text)

Critical CSS Requirements

The .blob-code cell MUST have white-space: pre to preserve whitespace and prevent wrapping:

.ohhighmark td.blob-code {
  white-space: pre;  /* REQUIRED - preserves all whitespace */
  font-family: ui-monospace, monospace;
  line-height: 20px;
}

Frontend JavaScript Integration

Target rows by line number:

// Select a specific line
const row = document.querySelector('[data-line-number="5"]');

// Highlight a line
row.style.backgroundColor = 'rgba(255, 255, 0, 0.2)';

// Get all table rows
const tableRows = document.querySelectorAll('tr[data-line-number]');

Contributing

Bug reports and pull requests are welcome!

Development Setup

$ git clone https://github.com/viacoffee/ohhighmark.git
$ cd ohhighmark
$ bundle install
$ rspec  # Run tests

License

This gem is available as open source under the terms of the MIT License.