diff --git a/lib/pressa/posts/gemini_writer.rb b/lib/pressa/posts/gemini_writer.rb
index bb0e9ad..213b579 100644
--- a/lib/pressa/posts/gemini_writer.rb
+++ b/lib/pressa/posts/gemini_writer.rb
@@ -23,7 +23,7 @@ module Pressa
rows << "=> #{link.href}"
end
rows << "" unless home_links.empty?
- rows << "Recent posts"
+ rows << "## Recent posts"
rows << ""
@posts_by_year.recent_posts(limit).each do |post|
@@ -31,7 +31,6 @@ module Pressa
end
rows << ""
- rows << "=> /posts/ Archive"
rows << "=> #{web_url_for("/")} Website"
rows << ""
@@ -39,11 +38,11 @@ module Pressa
Utils::FileWriter.write(path: file_path, content: rows.join("\n"))
end
- def write_archive(target_path:)
- rows = ["# Archive", ""]
+ def write_posts_index(target_path:)
+ rows = ["# #{@site.title} posts", "## Feed", ""]
- @posts_by_year.sorted_years.each do |year|
- rows << "=> /posts/#{year}/ #{year}"
+ @posts_by_year.all_posts.each do |post|
+ rows.concat(post_listing_lines(post))
end
rows << ""
@@ -51,8 +50,9 @@ module Pressa
rows << "=> #{web_url_for("/posts/")} Read on the web"
rows << ""
- file_path = File.join(target_path, "posts", "index.gmi")
- Utils::FileWriter.write(path: file_path, content: rows.join("\n"))
+ content = rows.join("\n")
+ Utils::FileWriter.write(path: File.join(target_path, "posts", "index.gmi"), content:)
+ Utils::FileWriter.write(path: File.join(target_path, "posts", "feed.gmi"), content:)
end
def write_year_indexes(target_path:)
@@ -84,7 +84,7 @@ module Pressa
rows << gemtext_body unless gemtext_body.empty?
rows << "" unless rows.last.to_s.empty?
- rows << "=> /posts/ Back to archive"
+ rows << "=> /posts Back to posts"
rows << "=> #{web_url_for("#{post.path}/")} Read on the web" if include_web_link?(post)
rows << ""
@@ -99,12 +99,12 @@ module Pressa
month = month_posts.month
rows << "## #{month.name}"
month_posts.sorted_posts.each do |post|
- rows.concat(post_archive_lines(post))
+ rows.concat(post_listing_lines(post))
end
rows << ""
end
- rows << "=> /posts/ Back to archive"
+ rows << "=> /posts Back to posts"
rows << "=> #{web_url_for("/posts/#{year}/")} Read on the web"
rows << ""
@@ -117,12 +117,12 @@ module Pressa
rows = ["# #{month.name} #{year}", ""]
month_posts.sorted_posts.each do |post|
- rows.concat(post_archive_lines(post))
+ rows.concat(post_listing_lines(post))
end
rows << ""
rows << "=> /posts/#{year}/ Back to year"
- rows << "=> /posts/ Back to archive"
+ rows << "=> /posts Back to posts"
rows << "=> #{web_url_for("/posts/#{year}/#{month.padded}/")} Read on the web"
rows << ""
@@ -134,7 +134,7 @@ module Pressa
"=> #{post.path}/ #{post.date.strftime("%Y-%m-%d")} - #{post.title}"
end
- def post_archive_lines(post)
+ def post_listing_lines(post)
rows = [post_link_line(post)]
rows << "=> #{post.link}" if post.link_post?
rows
diff --git a/lib/pressa/posts/plugin.rb b/lib/pressa/posts/plugin.rb
index cdf1335..c0c3f14 100644
--- a/lib/pressa/posts/plugin.rb
+++ b/lib/pressa/posts/plugin.rb
@@ -45,9 +45,7 @@ module Pressa
writer = GeminiWriter.new(site:, posts_by_year: @posts_by_year)
writer.write_posts(target_path:)
writer.write_recent_posts(target_path:, limit: gemini_recent_posts_limit(site))
- writer.write_archive(target_path:)
- writer.write_year_indexes(target_path:)
- writer.write_month_rollups(target_path:)
+ writer.write_posts_index(target_path:)
end
private
diff --git a/lib/pressa/utils/gemtext_renderer.rb b/lib/pressa/utils/gemtext_renderer.rb
index 03f099c..518dd56 100644
--- a/lib/pressa/utils/gemtext_renderer.rb
+++ b/lib/pressa/utils/gemtext_renderer.rb
@@ -78,6 +78,10 @@ module Pressa
def convert_text_line(line, link_reference_definitions)
clean_text, links = extract_links(line, link_reference_definitions)
+ if !links.empty? && clean_inline_text(strip_links_from_text(line)).empty?
+ return render_link_rows(links)
+ end
+
rows = []
inline_text = clean_inline_text(clean_text)
rows << inline_text unless inline_text.empty?
@@ -130,7 +134,7 @@ module Pressa
end
def link_only_list_item?(text, link_reference_definitions)
- clean_text, links = extract_links(text, link_reference_definitions)
+ _clean_text, links = extract_links(text, link_reference_definitions)
return false if links.empty?
remaining_text = strip_links_from_text(text)
@@ -183,7 +187,26 @@ module Pressa
cleaned.gsub!(/\*([^*]+)\*/, '\1')
cleaned.gsub!(/_([^_]+)_/, '\1')
cleaned.gsub!(/\s+/, " ")
- CGI.unescapeHTML(cleaned).strip
+ cleaned = CGI.unescapeHTML(cleaned)
+ cleaned = decode_named_html_entities(cleaned)
+ cleaned.strip
+ end
+
+ def decode_named_html_entities(text)
+ text.gsub(/&([A-Za-z]+);/) do
+ entity = Regexp.last_match(1).downcase
+
+ case entity
+ when "darr" then "\u2193"
+ when "uarr" then "\u2191"
+ when "larr" then "\u2190"
+ when "rarr" then "\u2192"
+ when "hellip" then "..."
+ when "nbsp" then " "
+ else
+ "{Regexp.last_match(1)};"
+ end
+ end
end
def strip_html_tags(text)
diff --git a/lib/pressa/views/icons.rb b/lib/pressa/views/icons.rb
index 6a3c7dd..32396c3 100644
--- a/lib/pressa/views/icons.rb
+++ b/lib/pressa/views/icons.rb
@@ -19,6 +19,10 @@ module Pressa
svg(class_name: "icon icon-code", view_box: "0 0 640 512", path: IconPath::CODE)
end
+ def gemini
+ svg(class_name: "icon icon-gemini", view_box: "0 0 576 512", path: IconPath::GEMINI)
+ end
+
private_class_method def svg(class_name:, view_box:, path:)
""
end
@@ -28,6 +32,7 @@ module Pressa
GITHUB = "M165.9 50.5996c0 -2 -2.30078 -3.59961 -5.2002 -3.59961c-3.2998 -0.299805 -5.60059 1.2998 -5.60059 3.59961c0 2 2.30078 3.60059 5.2002 3.60059c3 0.299805 5.60059 -1.2998 5.60059 -3.60059zM134.8 55.0996c0.700195 2 3.60059 3 6.2002 2.30078 c3 -0.900391 4.90039 -3.2002 4.2998 -5.2002c-0.599609 -2 -3.59961 -3 -6.2002 -2c-3 0.599609 -5 2.89941 -4.2998 4.89941zM179 56.7998c2.90039 0.299805 5.59961 -1 5.90039 -2.89941c0.299805 -2 -1.7002 -3.90039 -4.60059 -4.60059 c-3 -0.700195 -5.59961 0.600586 -5.89941 2.60059c-0.300781 2.2998 1.69922 4.19922 4.59961 4.89941zM244.8 440c138.7 0 251.2 -105.3 251.2 -244c0 -110.9 -67.7998 -205.8 -167.8 -239c-12.7002 -2.2998 -17.2998 5.59961 -17.2998 12.0996 c0 8.2002 0.299805 49.9004 0.299805 83.6006c0 23.5 -7.7998 38.5 -17 46.3994c55.8994 6.30078 114.8 14 114.8 110.5c0 27.4004 -9.7998 41.2002 -25.7998 58.9004c2.59961 6.5 11.0996 33.2002 -2.60059 67.9004c-20.8994 6.59961 -69 -27 -69 -27 c-20 5.59961 -41.5 8.5 -62.7998 8.5s-42.7998 -2.90039 -62.7998 -8.5c0 0 -48.0996 33.5 -69 27c-13.7002 -34.6006 -5.2002 -61.4004 -2.59961 -67.9004c-16 -17.5996 -23.6006 -31.4004 -23.6006 -58.9004c0 -96.1992 56.4004 -104.3 112.3 -110.5 c-7.19922 -6.59961 -13.6992 -17.6992 -16 -33.6992c-14.2998 -6.60059 -51 -17.7002 -72.8994 20.8994c-13.7002 23.7998 -38.6006 25.7998 -38.6006 25.7998c-24.5 0.300781 -1.59961 -15.3994 -1.59961 -15.3994c16.4004 -7.5 27.7998 -36.6006 27.7998 -36.6006 c14.7002 -44.7998 84.7002 -29.7998 84.7002 -29.7998c0 -21 0.299805 -55.2002 0.299805 -61.3994c0 -6.5 -4.5 -14.4004 -17.2998 -12.1006c-99.7002 33.4004 -169.5 128.3 -169.5 239.2c0 138.7 106.1 244 244.8 244zM97.2002 95.0996 c1.2998 1.30078 3.59961 0.600586 5.2002 -1c1.69922 -1.89941 2 -4.19922 0.699219 -5.19922c-1.2998 -1.30078 -3.59961 -0.600586 -5.19922 1c-1.7002 1.89941 -2 4.19922 -0.700195 5.19922zM86.4004 103.2c0.699219 1 2.2998 1.2998 4.2998 0.700195 c2 -1 3 -2.60059 2.2998 -3.90039c-0.700195 -1.40039 -2.7002 -1.7002 -4.2998 -0.700195c-2 1 -3 2.60059 -2.2998 3.90039zM118.8 67.5996c1.2998 1.60059 4.2998 1.30078 6.5 -1c2 -1.89941 2.60059 -4.89941 1.2998 -6.19922 c-1.2998 -1.60059 -4.19922 -1.30078 -6.5 1c-2.2998 1.89941 -2.89941 4.89941 -1.2998 6.19922zM107.4 82.2998c1.59961 1.2998 4.19922 0.299805 5.59961 -2c1.59961 -2.2998 1.59961 -4.89941 0 -6.2002c-1.2998 -1 -4 0 -5.59961 2.30078 c-1.60059 2.2998 -1.60059 4.89941 0 5.89941z"
RSS = "M128.081 32.041c0 -35.3691 -28.6719 -64.041 -64.041 -64.041s-64.04 28.6719 -64.04 64.041s28.6719 64.041 64.041 64.041s64.04 -28.6729 64.04 -64.041zM303.741 -15.209c0.494141 -9.13477 -6.84668 -16.791 -15.9951 -16.79h-48.0693 c-8.41406 0 -15.4707 6.49023 -16.0176 14.8867c-7.29883 112.07 -96.9404 201.488 -208.772 208.772c-8.39648 0.545898 -14.8867 7.60254 -14.8867 16.0176v48.0693c0 9.14746 7.65625 16.4883 16.791 15.9941c154.765 -8.36328 278.596 -132.351 286.95 -286.95z M447.99 -15.4971c0.324219 -9.03027 -6.97168 -16.5029 -16.0049 -16.5039h-48.0684c-8.62598 0 -15.6455 6.83496 -15.999 15.4531c-7.83789 191.148 -161.286 344.626 -352.465 352.465c-8.61816 0.354492 -15.4531 7.37402 -15.4531 15.999v48.0684 c0 9.03418 7.47266 16.3301 16.5029 16.0059c234.962 -8.43555 423.093 -197.667 431.487 -431.487z"
CODE = "M278.9 -63.5l-61 17.7002c-6.40039 1.7998 -10 8.5 -8.2002 14.8994l136.5 470.2c1.7998 6.40039 8.5 10 14.8994 8.2002l61 -17.7002c6.40039 -1.7998 10 -8.5 8.2002 -14.8994l-136.5 -470.2c-1.89941 -6.40039 -8.5 -10.1006 -14.8994 -8.2002zM164.9 48.7002 c-4.5 -4.90039 -12.1006 -5.10059 -17 -0.5l-144.101 135.1c-5.09961 4.7002 -5.09961 12.7998 0 17.5l144.101 135c4.89941 4.60059 12.5 4.2998 17 -0.5l43.5 -46.3994c4.69922 -4.90039 4.2998 -12.7002 -0.800781 -17.2002l-90.5996 -79.7002l90.5996 -79.7002 c5.10059 -4.5 5.40039 -12.2998 0.800781 -17.2002zM492.1 48.0996c-4.89941 -4.5 -12.5 -4.2998 -17 0.600586l-43.5 46.3994c-4.69922 4.90039 -4.2998 12.7002 0.800781 17.2002l90.5996 79.7002l-90.5996 79.7998c-5.10059 4.5 -5.40039 12.2998 -0.800781 17.2002 l43.5 46.4004c4.60059 4.7998 12.2002 5 17 0.5l144.101 -135.2c5.09961 -4.7002 5.09961 -12.7998 0 -17.5z"
+ GEMINI = "M543.79 125.6l-224 -99.5996c-19.2002 -8.5 -44.4004 -8.5 -63.6006 0l-224 99.5996c-32.2002 14.2998 -40.3008 52.2998 -15.8008 74.7002l224 204.5c9.7998 9 25.3008 14.1992 41.6006 14.1992s31.8008 -5.19922 41.6006 -14.1992l224 -204.5c24.499 -22.4004 16.3994 -60.4004 -15.8008 -74.7002z"
end
end
end
diff --git a/lib/pressa/views/layout.rb b/lib/pressa/views/layout.rb
index 1e36ba9..99672b1 100644
--- a/lib/pressa/views/layout.rb
+++ b/lib/pressa/views/layout.rb
@@ -125,7 +125,7 @@ module Pressa
h1 do
a(href: site.url) { site.title }
end
- br
+
h4 do
plain "By "
a(href: site.url_for("/about")) { site.author }
@@ -134,7 +134,7 @@ module Pressa
nav(class: "remote") do
ul do
- html_remote_links.each do |link|
+ remote_nav_links.each do |link|
li(class: remote_link_class(link)) do
attrs = {"aria-label": link.label, href: remote_link_href(link.href)}
attrs[:rel] = "me" if mastodon_link?(link)
@@ -177,6 +177,92 @@ module Pressa
attrs[:defer] = true if scr.defer
script(**attrs)
end
+
+ render_gemini_fallback_script
+ end
+
+ def render_gemini_fallback_script
+ # Inline so the behavior ships with the base HTML layout without needing
+ # separate asset management for one small handler.
+ script do
+ raw(safe(<<~JS))
+ (function () {
+ function isPlainLeftClick(e) {
+ return (
+ e.button === 0 &&
+ !e.defaultPrevented &&
+ !e.metaKey &&
+ !e.ctrlKey &&
+ !e.shiftKey &&
+ !e.altKey
+ );
+ }
+
+ function setupGeminiFallback() {
+ var link = document.querySelector(
+ 'header.primary nav.remote li.gemini a[href^="gemini://"]'
+ );
+ if (!link) return;
+
+ link.addEventListener("click", function (e) {
+ if (!isPlainLeftClick(e)) return;
+
+ e.preventDefault();
+
+ var geminiHref = link.getAttribute("href");
+ var fallbackHref = "https://geminiprotocol.net";
+
+ var done = false;
+ var fallbackTimer = null;
+
+ function cleanup() {
+ if (fallbackTimer) window.clearTimeout(fallbackTimer);
+ document.removeEventListener("visibilitychange", onVisibilityChange);
+ window.removeEventListener("pagehide", onPageHide);
+ window.removeEventListener("blur", onBlur);
+ }
+
+ function markDone() {
+ done = true;
+ cleanup();
+ }
+
+ function onVisibilityChange() {
+ // If a handler opens and the browser backgrounded, consider it "successful".
+ if (document.visibilityState === "hidden") markDone();
+ }
+
+ function onPageHide() {
+ markDone();
+ }
+
+ function onBlur() {
+ // Some browsers blur the page when a protocol handler is invoked.
+ markDone();
+ }
+
+ document.addEventListener("visibilitychange", onVisibilityChange);
+ window.addEventListener("pagehide", onPageHide, { once: true });
+ window.addEventListener("blur", onBlur, { once: true });
+
+ // If we're still here shortly after attempting navigation, assume it failed.
+ fallbackTimer = window.setTimeout(function () {
+ if (done) return;
+ window.location.href = fallbackHref;
+ }, 900);
+
+ window.location.href = geminiHref;
+ });
+ }
+
+ if (document.readyState === "loading") {
+ document.addEventListener("DOMContentLoaded", setupGeminiFallback);
+ } else {
+ setupGeminiFallback();
+ }
+ })();
+ JS
+ end
end
def script_src(src)
@@ -208,8 +294,12 @@ module Pressa
site.html_output_options&.remote_links || []
end
+ def remote_nav_links
+ html_remote_links
+ end
+
def remote_link_href(href)
- return href if href.start_with?("http://", "https://")
+ return href if href.match?(/\A[a-z][a-z0-9+\-.]*:/i)
absolute_asset(href)
end
@@ -220,6 +310,16 @@ module Pressa
end
def remote_link_icon_markup(link)
+ # Gemini doesn't have an obvious, widely-recognized protocol icon.
+ # Use a simple custom SVG mark so it aligns like the other SVG icons.
+ if link.icon == "gemini"
+ return <<~SVG.strip
+
+ SVG
+ end
+
icon_renderer = remote_link_icon_renderer(link.icon)
return nil unless icon_renderer
@@ -232,6 +332,8 @@ module Pressa
when "github" then :github
when "rss" then :rss
when "code" then :code
+ # The Gemini SVG icon was too ambiguous in practice; render this as text instead.
+ when "gemini" then nil
end
end
diff --git a/public/css/style.css b/public/css/style.css
index 47ec4a9..00a40e2 100644
--- a/public/css/style.css
+++ b/public/css/style.css
@@ -160,7 +160,7 @@ header.primary .title {
header.primary h1,
header.primary h4 {
- display: inline-block;
+ display: block;
margin: 0;
padding: 0;
word-wrap: break-word;
@@ -180,6 +180,8 @@ header.primary h1 a:visited {
color: #f7f7f7;
}
+/* (protocol-link styles removed; Gemini now renders in the remote icon row) */
+
header.primary h4 {
font-size: 0.8rem;
line-height: 1.2;
@@ -264,6 +266,15 @@ header.primary nav ul li.github .icon {
color: #4183c4;
}
+header.primary nav ul li.gemini a,
+header.primary nav ul li.gemini a:visited {
+ color: #bdbdbd;
+}
+
+header.primary nav ul li.gemini a:hover {
+ color: #f7f7f7;
+}
+
footer {
padding: 0 env(safe-area-inset-right) 2rem env(safe-area-inset-left);
text-align: center;
diff --git a/site.toml b/site.toml
index ce3b44e..8d34338 100644
--- a/site.toml
+++ b/site.toml
@@ -22,17 +22,20 @@ styles = []
remote_links = [
{"label": "Mastodon", "href": "https://techhub.social/@sjs", "icon": "mastodon"},
{"label": "GitHub", "href": "https://github.com/samsonjs", "icon": "github"},
- {"label": "RSS", "href": "/feed.xml", "icon": "rss"}
+ {"label": "RSS", "href": "/feed.xml", "icon": "rss"},
+ {"label": "Gemini", "href": "gemini://samhuri.net", "icon": "gemini"}
]
[outputs.gemini]
recent_posts_limit = 20
home_links = [
- {"label": "About", "href": "/about/"},
- {"label": "Projects", "href": "/projects/"},
+ {"label": "About", "href": "/about"},
+ {"label": "Posts", "href": "/posts"},
+ {"label": "Projects", "href": "/projects"},
{"label": "Mastodon", "href": "https://techhub.social/@sjs"},
{"label": "GitHub", "href": "https://github.com/samsonjs"},
- {"label": "RSS", "href": "/feed.xml"},
+ {"label": "RSS (Gemini)", "href": "/posts/feed.gmi"},
+ {"label": "RSS (Web)", "href": "https://samhuri.net/feed.xml"},
{"label": "Email", "href": "mailto:sami@samhuri.net"}
]
exclude_public = [
diff --git a/test/posts/gemini_plugin_test.rb b/test/posts/gemini_plugin_test.rb
index 0720c0f..5bc9fab 100644
--- a/test/posts/gemini_plugin_test.rb
+++ b/test/posts/gemini_plugin_test.rb
@@ -69,8 +69,9 @@ class Pressa::Posts::GeminiPluginTest < Minitest::Test
assert(File.exist?(File.join(target_path, "index.gmi")))
assert(File.exist?(File.join(target_path, "posts/index.gmi")))
- assert(File.exist?(File.join(target_path, "posts/2025/index.gmi")))
- assert(File.exist?(File.join(target_path, "posts/2025/11/index.gmi")))
+ assert(File.exist?(File.join(target_path, "posts/feed.gmi")))
+ refute(File.exist?(File.join(target_path, "posts/2025/index.gmi")))
+ refute(File.exist?(File.join(target_path, "posts/2025/11/index.gmi")))
markdown_post = File.join(target_path, "posts/2025/11/markdown-only/index.gmi")
html_post = File.join(target_path, "posts/2025/11/html-heavy/index.gmi")
@@ -81,8 +82,8 @@ class Pressa::Posts::GeminiPluginTest < Minitest::Test
index_text = File.read(File.join(target_path, "index.gmi"))
markdown_text = File.read(markdown_post)
html_text = File.read(html_post)
- year_index = File.read(File.join(target_path, "posts/2025/index.gmi"))
- month_index = File.read(File.join(target_path, "posts/2025/11/index.gmi"))
+ archive_text = File.read(File.join(target_path, "posts/index.gmi"))
+ feed_text = File.read(File.join(target_path, "posts/feed.gmi"))
assert_includes(index_text, "=> /about/")
assert_includes(index_text, "=> https://techhub.social/@sjs")
@@ -92,12 +93,13 @@ class Pressa::Posts::GeminiPluginTest < Minitest::Test
assert_includes(html_text, "Read on the web")
assert_includes(markdown_text, "=> https://example.com")
assert_includes(html_text, "=> https://example.org")
- assert_includes(year_index, "## November")
- refute_includes(year_index, "=> /posts/2025/11/ November 2025")
- assert_match(%r{=> /posts/2025/11/link-post/ 2025-11-07 - Link Post\n=> https://example.net/story}, year_index)
- assert_includes(year_index, "=> /posts/2025/11/html-heavy/ 2025-11-06 - HTML Heavy")
- assert_includes(year_index, "=> /posts/2025/11/markdown-only/ 2025-11-05 - Markdown Only")
- assert_match(%r{=> /posts/2025/11/link-post/ 2025-11-07 - Link Post\n=> https://example.net/story}, month_index)
+ assert_includes(markdown_text, "=> /posts Back to posts")
+ assert_includes(archive_text, "# samhuri.net posts")
+ assert_includes(archive_text, "## Feed")
+ assert_match(%r{=> /posts/2025/11/link-post/ 2025-11-07 - Link Post\n=> https://example.net/story}, archive_text)
+ assert_includes(archive_text, "=> /posts/2025/11/html-heavy/ 2025-11-06 - HTML Heavy")
+ assert_includes(archive_text, "=> /posts/2025/11/markdown-only/ 2025-11-05 - Markdown Only")
+ assert_equal(archive_text, feed_text)
end
end
end
diff --git a/test/utils/gemtext_renderer_test.rb b/test/utils/gemtext_renderer_test.rb
index 86fd354..0831df2 100644
--- a/test/utils/gemtext_renderer_test.rb
+++ b/test/utils/gemtext_renderer_test.rb
@@ -50,4 +50,23 @@ class Pressa::Utils::GemtextRendererTest < Minitest::Test
refute_includes(rendered, "* GitHub: samsonjs")
refute_includes(rendered, "* Stack Overflow")
end
+
+ def test_render_decodes_common_named_html_entities
+ markdown = "a → b … and down ↓"
+ rendered = Pressa::Utils::GemtextRenderer.render(markdown)
+
+ assert_includes(rendered, "a \u2192 b ... and down \u2193")
+ refute_includes(rendered, "→")
+ refute_includes(rendered, "↓")
+ end
+
+ def test_render_collapses_link_only_text_lines_to_links
+ markdown = <<~MARKDOWN
+ ↓ Download volume.rb
+ MARKDOWN
+
+ rendered = Pressa::Utils::GemtextRenderer.render(markdown)
+
+ assert_equal("=> /f/volume.rb", rendered)
+ end
end
diff --git a/test/views/layout_test.rb b/test/views/layout_test.rb
index 6f41547..c186f44 100644
--- a/test/views/layout_test.rb
+++ b/test/views/layout_test.rb
@@ -112,6 +112,7 @@ class Pressa::Views::LayoutTest < Minitest::Test
html = Pressa::Views::Layout.new(
site: site_with_remote_links([
Pressa::OutputLink.new(label: "Mastodon", href: "https://techhub.social/@sjs", icon: "mastodon"),
+ Pressa::OutputLink.new(label: "Gemini", href: "gemini://samhuri.net", icon: "gemini"),
Pressa::OutputLink.new(label: "GitHub", href: "https://github.com/samsonjs", icon: "github"),
Pressa::OutputLink.new(label: "RSS", href: "/feed.xml", icon: "rss")
]),
@@ -120,9 +121,11 @@ class Pressa::Views::LayoutTest < Minitest::Test
).call
assert_includes(html, "href=\"https://techhub.social/@sjs\"")
+ assert_includes(html, "href=\"gemini://samhuri.net\"")
assert_includes(html, "href=\"https://github.com/samsonjs\"")
assert_includes(html, "href=\"https://samhuri.net/feed.xml\"")
assert_includes(html, "aria-label=\"Mastodon\"")
+ assert_includes(html, "aria-label=\"Gemini\"")
assert_includes(html, "aria-label=\"GitHub\"")
assert_includes(html, "aria-label=\"RSS\"")
end