The bmannconsulting.com website
at archivetrim 4.5 kB view raw
1# frozen_string_literal: true 2class BidirectionalLinksGenerator < Jekyll::Generator 3 def generate(site) 4 graph_nodes = [] 5 graph_edges = [] 6 7 all_notes = site.collections['notes'].docs 8 all_posts = site.posts.docs 9 all_pages = site.pages 10 all_journals = site.collections['journals'].docs 11 12 all_docs = all_notes + all_pages + all_journals + all_posts 13 14 link_extension = !!site.config["use_html_extension"] ? '.html' : '' 15 16 # Convert all Wiki/Roam-style double-bracket link syntax to plain HTML 17 # anchor tag elements (<a>) with "internal-link" CSS class 18 all_docs.each do |current_note| 19 all_docs.each do |note_potentially_linked_to| 20 note_title_regexp_pattern = Regexp.escape( 21 File.basename( 22 note_potentially_linked_to.basename, 23 File.extname(note_potentially_linked_to.basename) 24 ) 25 ).gsub('\_', '[ _]').gsub('\-', '[ -]').capitalize 26 27 title_from_data = note_potentially_linked_to.data['title'] 28 if title_from_data 29 title_from_data = Regexp.escape(title_from_data) 30 end 31 32 new_href = "#{site.baseurl}#{note_potentially_linked_to.url}#{link_extension}" 33 # new_href = "#{site.tags_url}#{title_from_data}" #TODO is this how we can get a link over to my notes site? 34 35 anchor_tag = "<a class='internal-link' href='#{new_href}'>\\1</a>" 36 37 # Replace double-bracketed links with label using note title 38 # [[A note about cats|this is a link to the note about cats]] 39 current_note.content.gsub!( 40 /\[\[#{note_title_regexp_pattern}\|(.+?)(?=\])\]\]/i, 41 anchor_tag 42 ) 43 44 # Replace double-bracketed links with label using note filename 45 # [[cats|this is a link to the note about cats]] 46 current_note.content.gsub!( 47 /\[\[#{title_from_data}\|(.+?)(?=\])\]\]/i, 48 anchor_tag 49 ) 50 51 # Replace double-bracketed links using note title 52 # [[a note about cats]] 53 current_note.content.gsub!( 54 /\[\[(#{title_from_data})\]\]/i, 55 anchor_tag 56 # "<a class='internal-link' href='https://notes.bmannconsulting.com/#page/#{title_from_data}'>\\1</a>" # this only works if there is a local note with the right title 57 ) 58 59 # Replace double-bracketed links using note filename 60 # [[cats]] 61 current_note.content.gsub!( 62 /\[\[(#{note_title_regexp_pattern})\]\]/i, 63 anchor_tag 64 ) 65 end 66 67 # At this point, all remaining double-bracket-wrapped words are 68 # pointing to non-existing pages, so let's turn them into disabled 69 # links by greying them out and changing the cursor 70 current_note.content = current_note.content.gsub( 71 /\[\[([^\]]+)\]\]/i, # match on the remaining double-bracket links 72 #<<~HTML.delete("\n") # replace with this HTML (\\1 is what was inside the brackets) 73 # <span title='There is no note that matches this link.' class='invalid-link'> 74 # <span class='invalid-link-brackets'>[[</span> 75 # \\1 76 # <span class='invalid-link-brackets'>]]</span></span> 77 #HTML 78 79 # This doesn't handle lots of cases, need a URI.escape 80 <<~HTML.delete("\n") # replace with this HTML (\\1 is what was inside the brackets) 81 <a href='https://notes.bmannconsulting.com/#/page/\\1' class='noteslink' target='_notes'>\\1</a> 82 HTML 83 ) 84 end 85 86 # Identify note backlinks and add them to each note 87 all_notes.each do |current_note| 88 # Nodes: Jekyll 89 notes_linking_to_current_note = all_notes.filter do |e| 90 e.content.include?(current_note.url) 91 end 92 93 # Nodes: Graph 94 graph_nodes << { 95 id: note_id_from_note(current_note), 96 path: "#{site.baseurl}#{current_note.url}#{link_extension}", 97 label: current_note.data['title'], 98 } unless current_note.path.include?('_notes/index.html') 99 100 # Edges: Jekyll 101 current_note.data['backlinks'] = notes_linking_to_current_note 102 103 # Edges: Graph 104 notes_linking_to_current_note.each do |n| 105 graph_edges << { 106 source: note_id_from_note(n), 107 target: note_id_from_note(current_note), 108 } 109 end 110 end 111 112 File.write('_includes/notes_graph.json', JSON.dump({ 113 edges: graph_edges, 114 nodes: graph_nodes, 115 })) 116 end 117 118 def note_id_from_note(note) 119 note.data['title'].bytes.join 120 end 121end