From 2f5b55febf4eccc632ceda8c97b0f4d67a240cfe Mon Sep 17 00:00:00 2001
From: Michael Menanno <1358708+mmenanno@users.noreply.github.com>
Date: Fri, 19 Dec 2025 12:17:59 -0500
Subject: [PATCH] Upgrade Ruby to 3.4 and fix build compatibility issues
- Upgrade Ruby from 3.2 to 3.4 (3.2 EOL in ~3 months)
- Update Bundler and gems to latest versions
- Upgrade Haml to 7.1 (blocking issue now resolved)
- Replace deprecated sass gem with sassc
- Replace Redcarpet with Kramdown to fix link_to nil error on Ruby 3.x
- Enable Uglifier harmony mode for ES6 syntax support
- Remove unused lib/unique_head.rb and lib/multilang.rb
Closes middleman/middleman#2818 workaround via Kramdown migration
---
.ruby-version | 2 +-
Gemfile | 23 +++--
Gemfile.lock | 158 +++++++++++++++++++----------------
config.rb | 23 ++---
lib/monokai_sublime_slate.rb | 2 +-
lib/multilang.rb | 16 ----
lib/nesting_unique_head.rb | 22 -----
lib/unique_head.rb | 24 ------
8 files changed, 110 insertions(+), 160 deletions(-)
delete mode 100644 lib/multilang.rb
delete mode 100644 lib/nesting_unique_head.rb
delete mode 100644 lib/unique_head.rb
diff --git a/.ruby-version b/.ruby-version
index be94e6f..7921bd0 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-3.2.2
+3.4.8
diff --git a/Gemfile b/Gemfile
index fbcbbe0..29e987d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,17 +1,16 @@
-ruby '~> 3.2'
+ruby '~> 3.4'
source 'https://rubygems.org'
# Middleman
-gem 'middleman', '~>4.5'
-gem 'middleman-syntax', '~> 3.3'
+gem 'middleman', '~>4.6'
+gem 'middleman-syntax', '~> 3.6'
gem 'middleman-autoprefixer', '~> 3.0'
-# middleman-sprocket can not be updated to 4.1.1 until the below issue is resolved
-# https://github.com/middleman/middleman/issues/2302
+# middleman-sprockets can not be updated to 4.1.1 due to autoprefixer seeing
+# SCSS comments before compilation: https://github.com/middleman/middleman/issues/2302
gem 'middleman-sprockets', '4.1.0'
-gem 'rouge', '~> 3.21'
-gem 'redcarpet', '~> 3.6.0'
-gem 'nokogiri', '~> 1.15.4'
-gem 'sass'
-# Haml can't be updated to 6.0 due to a monkey patch in middleman-syntax that needs to be fixed
-# https://github.com/middleman/middleman-syntax/issues/80
-gem 'haml', '~> 5.2'
+gem 'rouge', '~> 3.30'
+gem 'kramdown', '~> 2.5'
+gem 'kramdown-parser-gfm', '~> 1.1'
+gem 'nokogiri', '~> 1.15.7'
+gem 'sassc'
+gem 'haml', '~> 7.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 5a44a50..803cc26 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,87 +1,104 @@
GEM
remote: https://rubygems.org/
specs:
- activesupport (7.0.8)
- concurrent-ruby (~> 1.0, >= 1.0.2)
+ activesupport (8.1.1)
+ base64
+ bigdecimal
+ concurrent-ruby (~> 1.0, >= 1.3.1)
+ connection_pool (>= 2.2.5)
+ drb
i18n (>= 1.6, < 2)
+ json
+ logger (>= 1.4.2)
minitest (>= 5.1)
- tzinfo (~> 2.0)
- addressable (2.8.5)
- public_suffix (>= 2.0.2, < 6.0)
- autoprefixer-rails (10.4.15.0)
+ securerandom (>= 0.3)
+ tzinfo (~> 2.0, >= 2.0.5)
+ uri (>= 0.13.1)
+ addressable (2.8.8)
+ public_suffix (>= 2.0.2, < 8.0)
+ autoprefixer-rails (10.4.21.0)
execjs (~> 2)
- backports (3.24.1)
+ base64 (0.3.0)
+ bigdecimal (4.0.1)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
- concurrent-ruby (1.2.2)
- contracts (0.17)
- dotenv (2.8.1)
- erubis (2.7.0)
- execjs (2.9.1)
+ concurrent-ruby (1.3.6)
+ connection_pool (3.0.2)
+ contracts (0.17.2)
+ dotenv (3.2.0)
+ drb (2.2.3)
+ erubi (1.13.1)
+ execjs (2.10.0)
fast_blank (1.0.1)
- fastimage (2.2.7)
- ffi (1.16.3)
- haml (5.2.2)
- temple (>= 0.8.0)
+ fastimage (2.4.0)
+ ffi (1.17.2)
+ haml (7.1.0)
+ temple (>= 0.8.2)
+ thor
tilt
hamster (3.0.0)
concurrent-ruby (~> 1.0)
- hashie (3.6.0)
- i18n (1.6.0)
+ hashie (5.0.0)
+ i18n (1.14.7)
concurrent-ruby (~> 1.0)
- kramdown (2.4.0)
- rexml
- listen (3.8.0)
+ json (2.18.0)
+ kramdown (2.5.1)
+ rexml (>= 3.3.9)
+ kramdown-parser-gfm (1.1.0)
+ kramdown (~> 2.0)
+ listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
+ logger (1.7.0)
memoist (0.16.2)
- middleman (4.5.0)
- coffee-script (~> 2.2)
- haml (>= 4.0.5)
- kramdown (>= 2.3.0)
- middleman-cli (= 4.5.0)
- middleman-core (= 4.5.0)
+ middleman (4.6.2)
+ middleman-cli (= 4.6.2)
+ middleman-core (= 4.6.2)
middleman-autoprefixer (3.0.0)
autoprefixer-rails (~> 10.0)
middleman-core (>= 4.0.0)
- middleman-cli (4.5.0)
- thor (>= 0.17.0, < 2.0)
- middleman-core (4.5.0)
- activesupport (>= 6.1, < 7.1)
+ middleman-cli (4.6.2)
+ thor (>= 0.17.0, < 2)
+ middleman-core (4.6.2)
+ activesupport (>= 6.1)
addressable (~> 2.4)
- backports (~> 3.6)
bundler (~> 2.0)
- contracts (~> 0.13)
+ coffee-script (~> 2.2)
+ contracts
dotenv
- erubis
+ erubi
execjs (~> 2.0)
fast_blank
fastimage (~> 2.0)
+ haml (>= 4.0.5)
hamster (~> 3.0)
- hashie (~> 3.4)
- i18n (~> 1.6.0)
+ hashie (>= 3.4, < 6.0)
+ i18n (>= 1.6, < 1.15)
+ kramdown (~> 2.4)
listen (~> 3.0)
memoist (~> 0.14)
padrino-helpers (~> 0.15.0)
parallel
- rack (>= 1.4.5, < 3)
+ rack (>= 3)
+ rackup
sassc (~> 2.0)
servolux
- tilt (~> 2.0.9)
+ tilt (~> 2.2)
toml
- uglifier (~> 3.0)
+ uglifier (>= 3, < 5)
webrick
middleman-sprockets (4.1.0)
middleman-core (~> 4.0)
sprockets (>= 3.0)
- middleman-syntax (3.3.0)
+ middleman-syntax (3.6.1)
middleman-core (>= 3.2)
rouge (~> 3.2)
- mini_portile2 (2.8.5)
- minitest (5.20.0)
- nokogiri (1.15.4)
+ mini_portile2 (2.8.9)
+ minitest (6.0.0)
+ prism (~> 1.5)
+ nokogiri (1.15.7)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
padrino-helpers (0.15.3)
@@ -89,55 +106,56 @@ GEM
padrino-support (= 0.15.3)
tilt (>= 1.4.1, < 3)
padrino-support (0.15.3)
- parallel (1.23.0)
+ parallel (1.27.0)
parslet (2.0.0)
- public_suffix (5.0.3)
- racc (1.7.1)
- rack (2.2.8)
+ prism (1.7.0)
+ public_suffix (7.0.0)
+ racc (1.8.1)
+ rack (3.2.4)
+ rackup (2.3.1)
+ rack (>= 3)
rb-fsevent (0.11.2)
- rb-inotify (0.10.1)
+ rb-inotify (0.11.1)
ffi (~> 1.0)
- redcarpet (3.6.0)
- rexml (3.2.6)
+ rexml (3.4.4)
rouge (3.30.0)
- sass (3.7.4)
- sass-listen (~> 4.0.0)
- sass-listen (4.0.0)
- rb-fsevent (~> 0.9, >= 0.9.4)
- rb-inotify (~> 0.9, >= 0.9.7)
sassc (2.4.0)
ffi (~> 1.9)
+ securerandom (0.4.1)
servolux (0.13.0)
- sprockets (4.2.1)
+ sprockets (4.2.2)
concurrent-ruby (~> 1.0)
+ logger
rack (>= 2.2.4, < 4)
- temple (0.10.3)
- thor (1.3.0)
- tilt (2.0.11)
+ temple (0.10.4)
+ thor (1.4.0)
+ tilt (2.6.1)
toml (0.3.0)
parslet (>= 1.8.0, < 3.0.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
- uglifier (3.2.0)
+ uglifier (4.2.1)
execjs (>= 0.3.0, < 3)
- webrick (1.8.1)
+ uri (1.1.1)
+ webrick (1.9.2)
PLATFORMS
ruby
DEPENDENCIES
- haml (~> 5.2)
- middleman (~> 4.5)
+ haml (~> 7.1)
+ kramdown (~> 2.5)
+ kramdown-parser-gfm (~> 1.1)
+ middleman (~> 4.6)
middleman-autoprefixer (~> 3.0)
middleman-sprockets (= 4.1.0)
- middleman-syntax (~> 3.3)
- nokogiri (~> 1.15.4)
- redcarpet (~> 3.6.0)
- rouge (~> 3.21)
- sass
+ middleman-syntax (~> 3.6)
+ nokogiri (~> 1.15.7)
+ rouge (~> 3.30)
+ sassc
RUBY VERSION
- ruby 3.2.2p53
+ ruby 3.4.8p72
BUNDLED WITH
- 2.4.21
+ 2.7.2
diff --git a/config.rb b/config.rb
index 6f8b677..5338658 100644
--- a/config.rb
+++ b/config.rb
@@ -1,18 +1,14 @@
-# Unique header generation
-require './lib/unique_head.rb'
+require 'uglifier'
# Markdown
-set :markdown_engine, :redcarpet
+set :markdown_engine, :kramdown
set :markdown,
- fenced_code_blocks: true,
- smartypants: true,
- disable_indented_code_blocks: true,
- prettify: true,
- strikethrough: true,
- tables: true,
- with_toc_data: true,
- no_intra_emphasis: true,
- renderer: UniqueHeadCounter
+ input: 'GFM',
+ auto_ids: true,
+ hard_wrap: false,
+ smart_quotes: ['lsquo', 'rsquo', 'ldquo', 'rdquo'],
+ syntax_highlighter: :rouge,
+ syntax_highlighter_opts: { guess_lang: true }
# Assets
set :css_dir, 'stylesheets'
@@ -24,7 +20,6 @@
activate :syntax
ready do
require './lib/monokai_sublime_slate.rb'
- require './lib/multilang.rb'
end
activate :sprockets
@@ -50,7 +45,7 @@
# If you're having trouble with Middleman hanging, commenting
# out the following two lines has been known to help
activate :minify_css
- activate :minify_javascript
+ activate :minify_javascript, compressor: -> { Uglifier.new(harmony: true) }
# activate :gzip
end
diff --git a/lib/monokai_sublime_slate.rb b/lib/monokai_sublime_slate.rb
index cd2de33..ca82fbf 100644
--- a/lib/monokai_sublime_slate.rb
+++ b/lib/monokai_sublime_slate.rb
@@ -92,4 +92,4 @@ class MonokaiSublimeSlate < CSSTheme
Operator, :fg => :bright_pink
end
end
- end
+end
diff --git a/lib/multilang.rb b/lib/multilang.rb
deleted file mode 100644
index 36fbe5b..0000000
--- a/lib/multilang.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Multilang
- def block_code(code, full_lang_name)
- if full_lang_name
- parts = full_lang_name.split('--')
- rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified
- super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match|
- match + " tab-" + full_lang_name
- end
- else
- super(code, full_lang_name)
- end
- end
-end
-
-require 'middleman-core/renderers/redcarpet'
-Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang
diff --git a/lib/nesting_unique_head.rb b/lib/nesting_unique_head.rb
deleted file mode 100644
index 0127837..0000000
--- a/lib/nesting_unique_head.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# Nested unique header generation
-require 'middleman-core/renderers/redcarpet'
-
-class NestingUniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
- def initialize
- super
- @@headers_history = {} if !defined?(@@headers_history)
- end
-
- def header(text, header_level)
- friendly_text = text.gsub(/<[^>]*>/,"").parameterize
- @@headers_history[header_level] = text.parameterize
-
- if header_level > 1
- for i in (header_level - 1).downto(1)
- friendly_text.prepend("#{@@headers_history[i]}-") if @@headers_history.key?(i)
- end
- end
-
- return "#{text}"
- end
-end
diff --git a/lib/unique_head.rb b/lib/unique_head.rb
deleted file mode 100644
index d42bab2..0000000
--- a/lib/unique_head.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# Unique header generation
-require 'middleman-core/renderers/redcarpet'
-require 'digest'
-class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
- def initialize
- super
- @head_count = {}
- end
- def header(text, header_level)
- friendly_text = text.gsub(/<[^>]*>/,"").parameterize
- if friendly_text.strip.length == 0
- # Looks like parameterize removed the whole thing! It removes many unicode
- # characters like Chinese and Russian. To get a unique URL, let's just
- # URI escape the whole header
- friendly_text = Digest::SHA1.hexdigest(text)[0,10]
- end
- @head_count[friendly_text] ||= 0
- @head_count[friendly_text] += 1
- if @head_count[friendly_text] > 1
- friendly_text += "-#{@head_count[friendly_text]}"
- end
- return "#{text}"
- end
-end