html_toc 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/html_toc.rb +168 -0
  3. metadata +48 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c62fb2eeee42d1e49865ac7dd47360b2509f2336
4
+ data.tar.gz: 8aa27790eb4ea76551f091fe092edda139eb8eb4
5
+ SHA512:
6
+ metadata.gz: ecf0a363447ad1ad85b3f4c79ea0e8103622cdff38b360d067b99e77aad3b3d796407defc315b72ee35dd8d194b1a57a8c9550f81f6122f44dc3fbdc8d89036f
7
+ data.tar.gz: f9866cfd75f3fcbdf92a85eeca90752b0e160cc226af0b144485269f3b0d7ec3a3794ae1877d557f9bc8ec033d650ea0653850533ef47b7b58d381328a51a158
data/lib/html_toc.rb ADDED
@@ -0,0 +1,168 @@
1
+ require 'rexml/document'
2
+
3
+ module HtmlToc
4
+
5
+ #Primary method call
6
+ def self.process source, h_tags=Range.new(2, 6), show_toggle=false, use_numbers=false
7
+
8
+ #Search regex for {{toc}}
9
+ token = /\[\[[tT][oO][cC]\]\]/
10
+
11
+ #If there is no token, just return the source
12
+ if source !~ token then
13
+ return source
14
+ end
15
+
16
+ #Initialize here for later
17
+ toc = ""
18
+ refnum = ""
19
+ d1 = 0
20
+ d2 = 0
21
+ d3 = 0
22
+ d4 = 0
23
+ d5 = 0
24
+ d6 = 0
25
+
26
+ #Make a copy of the source, in case we need to
27
+ #preserve the original string
28
+ result = source
29
+
30
+ #Loop through the tags range to get the header tags
31
+ tags_hash = Hash.new
32
+
33
+ depth = 0
34
+ h_tags.each do |x|
35
+ #Get the depth
36
+ depth += 1
37
+
38
+ #Regex for indexed header tags
39
+ test = /<h#{x}(?: .*?)?>(.*?)<\/h#{x}>/
40
+
41
+ #Scan, and use the resulting MatchData objects
42
+ #to populate the hash
43
+ result.scan(test) do
44
+ m=Regexp.last_match
45
+ tags_hash[m.begin(0)] = Hx.new(m, depth)
46
+ end #result.scan(test) do
47
+ end #tags.each do
48
+
49
+ #Execute this block only if we have indexed headers
50
+ if tags_hash.length > 0 then
51
+ #Sort the hash. tags becomes an array with each element consisting
52
+ #of an array with two objects: the integer key and the Hx value
53
+ tags = tags_hash.sort_by { |k, v| k }
54
+
55
+ #Start with the last tag and work towards the front: this way,
56
+ #the begin index of subsequent headers will not be moved.
57
+ tags.reverse.each do |elem|
58
+ #Replace the section in the text with the corresponding d_anchor
59
+ result[elem[1].start_index..elem[1].end_index]=elem[1].text
60
+ end #tags.reverse.each do
61
+
62
+ #Now move forward through the array and build the toc itself
63
+ toc = "<div id='__toc'>\n"
64
+ toc += "<div id='__toc_header'>Contents"
65
+ if show_toggle then
66
+ toc+=" [<span id='__toc_toggle' onclick='ShowHideToc();'>Hide</span>]"
67
+ end
68
+ toc+="</div>\n"
69
+ toc+="<div id='__toc_content' style='display:block'>\n"
70
+ tags.each do |elem|
71
+ if use_numbers
72
+ case elem[1].depth
73
+ when 1
74
+ d1+=1
75
+ d2 = 0
76
+ d3 = 0
77
+ d4 = 0
78
+ d5 = 0
79
+ d6 = 0
80
+ refnum = "#{d1} "
81
+ when 2
82
+ d2+=1
83
+ d3 = 0
84
+ d4 = 0
85
+ d5 = 0
86
+ d6 = 0
87
+ refnum = "#{d1}.#{d2} "
88
+ when 3
89
+ d3+=1
90
+ d4 = 0
91
+ d5 = 0
92
+ d6 = 0
93
+ refnum = "#{d1}.#{d2}.#{d3} "
94
+ when 4
95
+ d4+=1
96
+ d5 = 0
97
+ d6 = 0
98
+ refnum = "#{d1}.#{d2}.#{d3}.#{d4} "
99
+ when 5
100
+ d5+=1
101
+ d6 = 0
102
+ refnum = "#{d1}.#{d2}.#{d3}.#{d4}.#{d5} "
103
+ when 6
104
+ d6+=1
105
+ refnum = "#{d1}.#{d2}.#{d3}.#{d4}.#{d5}.#{d6} "
106
+ end #case elem[1].depth
107
+ end #if use_numbers
108
+
109
+ toc+=elem[1].l_anchor refnum
110
+ end
111
+ toc+="</div>\n" #end __toc_content
112
+ toc+="</div>\n" #end __toc
113
+
114
+ end #if tags_hash.length > 0
115
+
116
+ #The location of the toc token may have changed, so get its location
117
+ toc_md = result.match(token)
118
+ result[toc_md.begin(0)..toc_md.end(0)] = toc
119
+
120
+ result
121
+ end #self.process
122
+
123
+ private
124
+
125
+ class Hx
126
+ attr_reader :depth, :text, :start_index, :end_index
127
+
128
+ @@unique_id = 0
129
+
130
+ def initialize md, d
131
+ @depth = d
132
+ @text = md.to_s
133
+ @start_index = md.begin(0)
134
+ @end_index = md.end(0)
135
+
136
+ #If the tag does not have an ID, give it one
137
+ tag_id = @text.match(/\bid(\s*?)=(\s*?)(["'])(.*?)\3/)
138
+ if tag_id == nil
139
+ @@unique_id += 1
140
+ id = " id='_id__#{@@unique_id}'"
141
+ snip = @text.index('>') #get the location of the first >
142
+ @text.insert(snip, id)
143
+ end
144
+ end
145
+
146
+ def id
147
+ #TODO Allow for undelimited attribute values, as in HTML5
148
+ tag_id = @text.match(/\bid(\s*?)=(\s*?)(["'])(.*?)\3/)
149
+
150
+ if tag_id == nil
151
+ ""
152
+ else
153
+ tag_id[0].to_s.match(/(["'])(.*?)\1/)[0].to_s[1..-2]
154
+ end
155
+ end
156
+
157
+ def inner_text
158
+ snip_start = @text.to_s.index('>') #Get the index of the first >
159
+ snip_end = @text.to_s.rindex('<') #Get the index of the last <
160
+ @text.to_s[(snip_start+1)..(snip_end-1)] #return everyting in between
161
+ end
162
+
163
+ def l_anchor refnum=""
164
+ "<div class='__toc_level_#{@depth}'><a href='##{id}'>#{refnum}#{inner_text}</a></div>\n"
165
+ end
166
+
167
+ end
168
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: html_toc
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gregory Gadow
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-09 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Do a case-insensitive search on an HTML document for the token [[toc]].
14
+ If present, scan the document for header tags in a given range, verify that they
15
+ have an id attribute and give them one if needed, then generate a group of links
16
+ pointing to those headers with the header text used as the link text. This group
17
+ of links then replaces the token.
18
+ email: gpg@gregory-gadow.net
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - lib/html_toc.rb
24
+ homepage: http://rubygems.org/gems/html_toc
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.2.2
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Generate and Insert a Table of Contents into a HTML Document
48
+ test_files: []