|
| 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) |
0 commit comments