Skip to content

Commit 4d947f9

Browse files
committed
plugins: add clickable id tags (anchors) to list items
- each text block is now referenceable - direct linking to each snippet from within backlinks
1 parent 29d9744 commit 4d947f9

File tree

2 files changed

+91
-0
lines changed

2 files changed

+91
-0
lines changed

_plugins/auto-anchor.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# frozen_string_literal: true
2+
# This file is based on code from https://github.com/bitcoinops/bitcoinops.github.io
3+
4+
# Automatically adds id tags (anchors) to list items
5+
6+
require 'digest/md5'
7+
8+
def generate_slug(text)
9+
# Remove double-quotes from titles before attempting to slugify
10+
text.gsub!('"', '')
11+
# Remove whitespace character from the end and use Liquid/Jekyll slugify filter
12+
slug_text = "{{ \"#{text.rstrip}\" | slugify: 'latin' }}"
13+
# use the digest library to create deterministic ids based on text
14+
id = Digest::MD5.hexdigest(slug_text)[0...7]
15+
slug = "\#b#{id}" # prefix with 'b', ids cannot start with a number
16+
slug
17+
end
18+
19+
def generate_anchor_list_link(anchor_link, class_name='anchor-list-link')
20+
# custom clickable bullet linking to an anchor
21+
"<a href=\"#{anchor_link}\" class=\"#{class_name}\">●</a>"
22+
end
23+
24+
def auto_anchor(content)
25+
# finds “bulleted” list items that start with hyphen (-) or asterisk (*)
26+
# adds anchor and clickable bullet
27+
content.gsub!(/^ *[\*-] .*?(?:\n\n|\z)/m) do |bulleted_paragraph|
28+
slug = generate_slug(bulleted_paragraph)
29+
bullet_character = bulleted_paragraph.match(/^ *([\*-])/)[1] # bullet can be '-' or '*'
30+
id_prefix = "#{bullet_character} {:#{slug} .anchor-list} #{generate_anchor_list_link(slug)}"
31+
bulleted_paragraph.sub!(/#{Regexp.quote(bullet_character)}/, id_prefix)
32+
end
33+
# finds “numbered” list items that start with number (1.)
34+
# adds anchor only
35+
content.gsub!(/^ *\d+\. .*?(?:\n\n|\z)/m) do |numbered_paragraph|
36+
slug = generate_slug(numbered_paragraph)
37+
id_prefix = "1. {:#{slug} .anchor-list .anchor-numbered}"
38+
numbered_paragraph.sub!(/\d+\./, id_prefix)
39+
end
40+
end
41+
42+
## Run automatically on all documents
43+
Jekyll::Hooks.register :documents, :pre_render do |post|
44+
## Don't process documents if YAML headers say: "auto_id: false"
45+
unless post.data["auto_id"] == false
46+
auto_anchor(post.content)
47+
end
48+
end
49+
50+
module TextFilter
51+
# This is a custom filter used in backlinks.html to
52+
# add anchor links to each backlink snippet
53+
def link_to_anchor(text, url)
54+
slug = generate_slug(text)
55+
id_prefix = generate_anchor_list_link("#{url}#{slug}", "backlink-link")
56+
text.sub!(/(?:-|\*|\d+\.)/, id_prefix) # this targets both “bulleted” and “numbered” list items
57+
text
58+
end
59+
end
60+
61+
Liquid::Template.register_filter(TextFilter)

assets/css/all.sass

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,3 +201,33 @@ a
201201
font-size: 0.85em
202202
color: #828282
203203

204+
@keyframes highlightfade
205+
from
206+
background: var(--target-color)
207+
to
208+
background: transparent
209+
210+
.anchor-list
211+
list-style: none
212+
&:target
213+
background: transparent
214+
animation-name: highlightfade
215+
animation-duration: 7s
216+
217+
.anchor-numbered
218+
list-style: decimal
219+
220+
.anchor-list-link
221+
color: var(--text-color)
222+
margin-left: -14px
223+
padding-right: 3px
224+
font-size: 0.45em
225+
display: inline-block
226+
position: relative
227+
top: -0.4em /* position the dot vertically in the middle of the container element */
228+
text-decoration: none
229+
230+
.backlink-link
231+
@extend .anchor-list-link
232+
font-size: 0.7em
233+
top: -0.25em

0 commit comments

Comments
 (0)