module HtmlToc
Public Class Methods
process(source:, h_tags: Range.new(2, 6), show_toggle: false, use_numbers: false)
click to toggle source
Primary method call
# File lib/html_toc.rb, line 6 def self.process(source:, h_tags: Range.new(2, 6), show_toggle: false, use_numbers: false) #Search regex for {{toc}} token = /<toc\s*\/>|\[\[toc\]\]/i #Allow for a token of either <toc/> or [[toc]] #If there is no token, just return the source if source !~ token then return source end #Initialize here for later toc = "" refnum = "" d1 = 0 d2 = 0 d3 = 0 d4 = 0 d5 = 0 d6 = 0 #Make a copy of the source, in case we need to #preserve the original string result = source #Loop through the tags range to get the header tags tags_hash = Hash.new depth = 0 h_tags.each do |x| #Get the depth depth += 1 #Regex for indexed header tags test = /<h#{x}(?: .*?)?>(.*?)<\/h#{x}>/i #Scan, and use the resulting MatchData objects #to populate the hash result.scan(test) do m=Regexp.last_match tags_hash[m.begin(0)] = Hx.new(m, depth) end #result.scan(test) do end #tags.each do #Execute this block only if we have indexed headers if tags_hash.length > 0 then #Sort the hash. tags becomes an array with each element consisting #of an array with two objects: the integer key and the Hx value tags = tags_hash.sort_by { |k, v| k } #Start with the last tag and work towards the front: this way, #the begin index of subsequent headers will not be moved. tags.reverse.each do |elem| #Replace the section in the text with the corresponding d_anchor result[elem[1].start_index..elem[1].end_index]=elem[1].text end #tags.reverse.each do #Now move forward through the array and build the toc itself toc = "<div id='__toc'>\n" toc += "<div id='__toc_header'>Contents" if show_toggle then toc+=" [<span id='__toc_toggle' onclick='ShowHideToc();'>Hide</span>]" end toc+="</div>\n" toc+="<div id='__toc_content' style='display:block'>\n" tags.each do |elem| if use_numbers case elem[1].depth when 1 d1+=1 d2 = 0 d3 = 0 d4 = 0 d5 = 0 d6 = 0 refnum = "#{d1} " when 2 d2+=1 d3 = 0 d4 = 0 d5 = 0 d6 = 0 refnum = "#{d1}.#{d2} " when 3 d3+=1 d4 = 0 d5 = 0 d6 = 0 refnum = "#{d1}.#{d2}.#{d3} " when 4 d4+=1 d5 = 0 d6 = 0 refnum = "#{d1}.#{d2}.#{d3}.#{d4} " when 5 d5+=1 d6 = 0 refnum = "#{d1}.#{d2}.#{d3}.#{d4}.#{d5} " when 6 d6+=1 refnum = "#{d1}.#{d2}.#{d3}.#{d4}.#{d5}.#{d6} " end #case elem[1].depth end #if use_numbers toc+=elem[1].l_anchor refnum end toc+="</div>\n" #end __toc_content toc+="</div>\n" #end __toc end #if tags_hash.length > 0 #The location of the toc token may have changed, so get its location toc_md = result.match(token) result[toc_md.begin(0)..toc_md.end(0)] = toc result end