*cloth and ToC

G

Guillaume Marcais

Is there a way to extract a table of content of a text with redcloth of
bluecloth?

What I have in mind is the ability to extract all the headers of a text
(h1., h2., etc. in textile) and generate: anchors within the html page
on these headers and a table of content with links to the headers.

So at the end of a wiki page I could add something like:

<div class="ToC">
ToC. <-- Replaced by *cloth bye the table of content -->
</div>

and get a beautiful and well linked table of content for free.

Is there already such a feature? Is it a reasonable feature request?

Guillaume.
 
A

Aredridel

Is there a way to extract a table of content of a text with redcloth of
bluecloth?

What I have in mind is the ability to extract all the headers of a text
(h1., h2., etc. in textile) and generate: anchors within the html page
on these headers and a table of content with links to the headers.

So at the end of a wiki page I could add something like:

<div class="ToC">
ToC. <-- Replaced by *cloth bye the table of content -->
</div>

and get a beautiful and well linked table of content for free.

Is there already such a feature? Is it a reasonable feature request?

Sounds like it would be better implemented as an output filter -- a
method that could take formatted HTML text as input, and add the table
of contents to the top, or return an array of the table of contents and
the HTML.

I'd be willing to take a stab at that if you'd like. It would be useful
to me, too, and useful to me to be independent of the markup engine.
 
G

Guillaume Marcais

--=-OgnaKGM2BXRXTpxgUKQg
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
[many insightful answers]

Well, with all the answers I got I finally wrote my own version. Right
now it support redcloth and textile (not markdown). The file is
attached.

To use it, with instiki for example, save it as redcloth_toc someplace
where it can be found by ruby (or add a -I option), and simply do:

$ ruby -r redcloth_toc /usr/bin/instiki --storage=/home/gus/tmp/storage

In my wiki pages I add:

<div class="rightHandSide">
Table of Content

toc2.

</div>

To get a beautiful ToC. The 2 in toc2. is optional. It is the maximum
depth of the table.

Hope this helps other people too.

Guillaume.

--=-OgnaKGM2BXRXTpxgUKQg
Content-Disposition: attachment; filename=redcloth_toc.rb
Content-Type: text/plain; name=redcloth_toc.rb; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

require 'redcloth'

class RedCloth
DEFAULT_RULES = [:refs_textile_header, :block_toc,
:textile, :markdown]

HEADER_RE = /(^\s*)(h(\d*))([^.]*)\.(?::(\S+))? (.*)$/

def refs_textile_header(text)
text.gsub!(HEADER_RE) do |m|
s,tag,num,atts,cite,content = $~[1..6]
header = content.gsub(/\s/, '+')
(@toc ||= []) << [num.to_i, header, content]
"#{ s }#{ tag }#{ atts }.#{ cite } <a name=\"#{ header }\">#{ content }</a>"
end
end

TOC_RE = /^toc(\d)?\.$/m

def block_toc(text)
if text =~ TOC_RE
unless @toc
text.gsub!( $&, "")
else
max_depth = $1 ? $1.to_i : 6
counter = Array.new(max_depth, 0)
toc_html = @toc.collect do |te|
i = te[0] - 1
if counter
num = ""
counter += 1
num += counter[0..i].join(".")
"\t<a href=\"##{ te[1] }\">#{ num } #{ te[2] }</a><br>"
end
end.join("\n")
text.gsub!($&, toc_html)
end
end
text.gsub!(TOC_RE, "Table of Content")
end
end

--=-OgnaKGM2BXRXTpxgUKQg--
 
G

Guillaume Marcais

--=-TwU1Cv15+RbsltOkxvVu
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

Sorry to respond to myself. Same thing, minus the bugs.

Guillaume.

--=-TwU1Cv15+RbsltOkxvVu
Content-Disposition: attachment; filename=redcloth_toc.rb
Content-Type: text/plain; name=redcloth_toc.rb; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

require 'redcloth'

class RedCloth
DEFAULT_RULES = [:refs_textile_header, :block_toc,
:textile, :markdown]

HEADER_RE = /(^\s*)(h(\d*))([^.]*)\.(?::(\S+))? (.*)$/

def refs_textile_header(text)
text.gsub!(HEADER_RE) do |m|
s,tag,num,atts,cite,content = $~[1..6]
header = content.gsub(/\s/, '+')
(@toc ||= []) << [num.to_i, header, content]
"#{ s }#{ tag }#{ atts }.#{ cite } <a name=\"#{ header }\">#{ content }</a>"
end
end

TOC_RE = /^toc(\d)?\.$/m

def block_toc(text)
if text =~ TOC_RE
unless @toc
text.gsub!( $&, "")
else
max_depth = $1 ? $1.to_i : 6
counter = Array.new(max_depth, 0)
toc_html = @toc.collect do |te|
i = te[0] - 1
p counter, i
if counter
num = ""
counter += 1
counter[i+1..-1] = Array.new(max_depth - i - 1, 0)
num += counter[0..i].join(".")
"\t<a href=\"##{ te[1] }\">#{ num } #{ te[2] }</a><br>"
end
end.join("\n")
text.gsub!($&, toc_html)
end
end
text.gsub!(TOC_RE, "Table of Content")
end
end

--=-TwU1Cv15+RbsltOkxvVu--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top