Last active
December 11, 2019 00:16
-
-
Save xziyue/c859c0ed736d8eea62c3e5e7c8d9c4cb to your computer and use it in GitHub Desktop.
A simple Ruby program to support indexing in Jekyll
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'digest/sha1' | |
module Jekyll | |
module JekyllIndexTermFilter | |
# html display name, index name | |
def getnames(matchedString) | |
stripped = matchedString.strip() | |
matchResult = stripped.match(/(?<!\\)@/) | |
if matchResult == nil then | |
[stripped, stripped] | |
else | |
indexLeft = [Regexp.last_match.begin(0) - 1, 0].max | |
htmlStr = stripped[0..indexLeft].strip() | |
indexStr = stripped[Regexp.last_match.begin(0)+1..-1].strip() | |
[htmlStr, indexStr] | |
end | |
end | |
def parsecontent(pattern, content, warnDuplicate) | |
rawIndexTerms = content.scan(pattern) | |
tagConv = Hash.new | |
counter = Hash.new(0) | |
for expr in rawIndexTerms do | |
names = getnames(expr[0]) | |
hashCode = Digest::SHA1.hexdigest(names[1]) | |
names.append(hashCode) | |
counter[names[1]] += 1 | |
tagConv[expr[0]] = names | |
end | |
if warnDuplicate then | |
counter.each do |k, v| | |
if v > 1 then | |
puts "\e[33mwarning: index term \"#{k}\" appeared #{v} times!\e[0m" | |
end | |
end | |
end | |
tagConv | |
end | |
def indexedbody(content) | |
pattern = /%{(?!#)(.*?)}%/ | |
tagConv = parsecontent(pattern, content, true) | |
# substitute normal tags | |
tagStyle = '<span class="indexed-term-style"><a name="%s"></a>%s</span>' | |
result = content.gsub(pattern){|s| tagStyle % [tagConv[$1][2], tagConv[$1][0]]} | |
tagLookup = Hash.new | |
tagConv.each do |k, v| | |
tagLookup[v[1]] = '#' + v[2] | |
end | |
# substitue special tags | |
specialPattern = /%{#(.*?)}%/ | |
result = result.gsub(specialPattern){|s| | |
# get command and arguments | |
spaceLoc = $1.index(' ') | |
cmd = $1[0..spaceLoc - 1] | |
if cmd == 'get_link' then | |
totalCmd = $1[spaceLoc + 1..-1] | |
#puts totalCmd | |
tagLookup.fetch(totalCmd, $1) | |
else | |
puts "\e[33mwarning: invalid command \"#{cmd}\" detected\e[0m" | |
$1 | |
end | |
} | |
result | |
end | |
def indexedterms(content) | |
pattern = /%{(.*?)}%/ | |
tagConv = parsecontent(pattern, content, false) | |
allTags = Array.new | |
tagConv.each do |key, val| | |
indexName = val[1].downcase | |
allTags.append([indexName, val[2]]) | |
end | |
allTags = allTags.sort{|a, b| a[0] <=> b[0]} | |
indexTermStyle = '<a class="index-a" href="#%s">%s</a>' | |
allLinks = Array.new | |
for item in allTags do | |
link = indexTermStyle % [item[1], item[0]] | |
allLinks.append(link) | |
end | |
allLinks.join(' • ') | |
end | |
end | |
end | |
Liquid::Template.register_filter(Jekyll::JekyllIndexTermFilter) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment