Skip to content

Commit

Permalink
plugins: mark external links with a "↗" symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
kouloumos committed Mar 28, 2023
1 parent e63de66 commit 29d9744
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ gem 'color_pound_spec_reporter'

# HTTP bindings to libcurl - https://github.com/taf2/curb
gem 'curb'

gem "nokogiri", "~> 1.13.10"
8 changes: 7 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,20 @@ GEM
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
mini_portile2 (2.8.1)
minitest (5.14.2)
minitest-reporters (1.4.2)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
nokogiri (1.13.10)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (5.0.0)
racc (1.6.2)
rake (13.0.1)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
Expand Down Expand Up @@ -92,7 +97,8 @@ DEPENDENCIES
kramdown-parser-gfm
minitest
minitest-reporters
nokogiri (~> 1.13.10)
rake

BUNDLED WITH
2.1.4
2.3.26
56 changes: 56 additions & 0 deletions _plugins/mark_external_links.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This file is based on code from https://github.com/riboseinc/jekyll-external-links

require 'nokogiri'
require 'uri'

# Given hostname and content, updates any found <a> elements as follows:
#
# - Adds `rel` attribute
# - Adds css class for external link icon
#
# Only processes external links where `href` starts with "http"
# and target host does not start with given site hostname.
def process_content(site_hostname, content, marker_css, link_selector)
content = Nokogiri::HTML(content)
content.css(link_selector).each do |a|
next unless a.get_attribute('href') =~ /\Ahttp/i
next if a.get_attribute('href') =~ /\Ahttp(s)?:\/\/#{site_hostname}\//i
next if a.inner_html.include? "icon-ext"
next if a.inner_html.include? "fa" # another icon is part of the link, e.g fa-github
next if a.inner_html.include? a.get_attribute('href') # plain links
a.set_attribute('rel', 'external')
a.set_attribute('class', marker_css)
end
return content.to_s
end

def mark_links_in_page_or_document(page_or_document)
site_hostname = URI(page_or_document.site.config['url']).host

# The link is marked as external by:
# (1) setting the rel attribute to external and
# (2) appending specified marker css class.
marker_css = "icon-ext"

# Determines which links to mark. E.g., usually we don’t want to mark navigational links.
link_selector = 'a:not(.internal-link)'

# Do not process assets or other non-HTML files
unless (page_or_document.respond_to?(:asset_file?) and
page_or_document.asset_file?) or
page_or_document.output_ext != ".html"
page_or_document.output = process_content(
site_hostname,
page_or_document.output,
marker_css,
link_selector)
end
end

Jekyll::Hooks.register :documents, :post_render do |doc|
mark_links_in_page_or_document(doc)
end

Jekyll::Hooks.register :pages, :post_render do |page|
mark_links_in_page_or_document(page)
end
10 changes: 10 additions & 0 deletions assets/css/all.sass
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,16 @@ a
color: #ccc
cursor: help

.icon-ext
&:after
position: relative
top: -0.5em
font-size: 0.7em
content: ""
color: #aaaaaa
display: inline-block
text-decoration: none

.backlink-box
position: relative
font-size: 0.9em
Expand Down

0 comments on commit 29d9744

Please sign in to comment.