html_toc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []