Module: HtmlToc

Defined in:
lib/html_toc.rb

Defined Under Namespace

Classes: Hx

Class Method Summary collapse

Class Method Details

.process(source, h_tags = Range.new(2, 6), show_toggle = false, use_numbers = false) ⇒ Object

Primary method call



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# 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 = /\[\[[tT][oO][cC]\]\]/

		#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}>/
	
		#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