Skip to content

Instantly share code, notes, and snippets.

@xziyue
Last active December 11, 2019 00:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xziyue/c859c0ed736d8eea62c3e5e7c8d9c4cb to your computer and use it in GitHub Desktop.
Save xziyue/c859c0ed736d8eea62c3e5e7c8d9c4cb to your computer and use it in GitHub Desktop.
A simple Ruby program to support indexing in Jekyll
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