##// END OF EJS Templates
Extract headings and TOC parsing from the textile formatter....
Jean-Philippe Lang -
r4262:024ff96ee27a
parent child
Show More
@@ -1,5 +1,5
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
1 # Redmine - project management software
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
@@ -451,7 +451,7 module ApplicationHelper
451 451 text = Redmine::WikiFormatting.to_html(Setting.text_formatting, text, :object => obj, :attribute => attr) { |macro, args| exec_macro(macro, obj, args) }
452 452
453 453 parse_non_pre_blocks(text) do |text|
454 [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links].each do |method_name|
454 [:parse_inline_attachments, :parse_wiki_links, :parse_redmine_links, :parse_headings].each do |method_name|
455 455 send method_name, text, project, obj, attr, only_path, options
456 456 end
457 457 end
@@ -673,6 +673,38 module ApplicationHelper
673 673 leading + (link || "#{prefix}#{sep}#{identifier}")
674 674 end
675 675 end
676
677 TOC_RE = /<p>\{\{([<>]?)toc\}\}<\/p>/i unless const_defined?(:TOC_RE)
678 HEADING_RE = /<h(1|2|3)( [^>]+)?>(.+?)<\/h(1|2|3)>/i unless const_defined?(:HEADING_RE)
679
680 # Headings and TOC
681 # Adds ids and links to headings and renders the TOC if needed unless options[:headings] is set to false
682 def parse_headings(text, project, obj, attr, only_path, options)
683 headings = []
684 text.gsub!(HEADING_RE) do
685 level, attrs, content = $1, $2, $3
686 item = strip_tags(content).strip
687 anchor = item.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
688 headings << [level, anchor, item]
689 "<h#{level} #{attrs} id=\"#{anchor}\">#{content}<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a></h#{level}>"
690 end unless options[:headings] == false
691
692 text.gsub!(TOC_RE) do
693 if headings.empty?
694 ''
695 else
696 div_class = 'toc'
697 div_class << ' right' if $1 == '>'
698 div_class << ' left' if $1 == '<'
699 out = "<ul class=\"#{div_class}\">"
700 headings.each do |level, anchor, item|
701 out << "<li class=\"heading#{level}\"><a href=\"##{anchor}\">#{item}</a></li>\n"
702 end
703 out << '</ul>'
704 out
705 end
706 end
707 end
676 708
677 709 # Same as Rails' simple_format helper without using paragraphs
678 710 def simple_format_without_paragraph(text)
@@ -112,7 +112,7 module Redmine
112 112 @included_wiki_pages ||= []
113 113 raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title)
114 114 @included_wiki_pages << page.title
115 out = textilizable(page.content, :text, :attachments => page.attachments)
115 out = textilizable(page.content, :text, :attachments => page.attachments, :headings => false)
116 116 @included_wiki_pages.pop
117 117 out
118 118 end
@@ -1,5 +1,5
1 1 # Redmine - project management software
2 # Copyright (C) 2006-2008 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
@@ -24,7 +24,7 module Redmine
24 24 include ActionView::Helpers::TagHelper
25 25
26 26 # auto_link rule after textile rules so that it doesn't break !image_url! tags
27 RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto, :inline_toc]
27 RULES = [:textile, :block_markdown_rule, :inline_auto_link, :inline_auto_mailto]
28 28
29 29 def initialize(*args)
30 30 super
@@ -61,51 +61,6 module Redmine
61 61 end
62 62 end
63 63
64 # Patch to add 'table of content' support to RedCloth
65 def textile_p_withtoc(tag, atts, cite, content)
66 # removes wiki links from the item
67 toc_item = content.gsub(/(\[\[([^\]\|]*)(\|([^\]]*))?\]\])/) { $4 || $2 }
68 # sanitizes titles from links
69 # see redcloth3.rb, same as "#{pre}#{text}#{post}"
70 toc_item.gsub!(LINK_RE) { [$2, $4, $9].join }
71 # sanitizes image links from titles
72 toc_item.gsub!(IMAGE_RE) { [$5].join }
73 # removes styles
74 # eg. %{color:red}Triggers% => Triggers
75 toc_item.gsub! %r[%\{[^\}]*\}([^%]+)%], '\\1'
76
77 # replaces non word caracters by dashes
78 anchor = toc_item.gsub(%r{[^\w\s\-]}, '').gsub(%r{\s+(\-+\s*)?}, '-')
79
80 unless anchor.blank?
81 if tag =~ /^h(\d)$/
82 @toc << [$1.to_i, anchor, toc_item]
83 end
84 atts << " id=\"#{anchor}\""
85 content = content + "<a href=\"##{anchor}\" class=\"wiki-anchor\">&para;</a>"
86 end
87 textile_p(tag, atts, cite, content)
88 end
89
90 alias :textile_h1 :textile_p_withtoc
91 alias :textile_h2 :textile_p_withtoc
92 alias :textile_h3 :textile_p_withtoc
93
94 def inline_toc(text)
95 text.gsub!(/<p>\{\{([<>]?)toc\}\}<\/p>/i) do
96 div_class = 'toc'
97 div_class << ' right' if $1 == '>'
98 div_class << ' left' if $1 == '<'
99 out = "<ul class=\"#{div_class}\">"
100 @toc.each do |heading|
101 level, anchor, toc_item = heading
102 out << "<li class=\"heading#{level}\"><a href=\"##{anchor}\">#{toc_item}</a></li>\n"
103 end
104 out << '</ul>'
105 out
106 end
107 end
108
109 64 AUTO_LINK_RE = %r{
110 65 ( # leading text
111 66 <\w+.*?>| # leading HTML tag, or
@@ -1,5 +1,5
1 1 # Redmine - project management software
2 # Copyright (C) 2006-2009 Jean-Philippe Lang
2 # Copyright (C) 2006-2010 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
@@ -422,6 +422,8 Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
422 422 h2. Subtitle with [[Wiki|another Wiki]] link
423 423
424 424 h2. Subtitle with %{color:red}red text%
425
426 h2. Subtitle with *some* _modifiers_
425 427
426 428 h1. Another title
427 429
@@ -436,11 +438,31 RAW
436 438 '<li class="heading2"><a href="#Subtitle-with-a-Wiki-link">Subtitle with a Wiki link</a></li>' +
437 439 '<li class="heading2"><a href="#Subtitle-with-another-Wiki-link">Subtitle with another Wiki link</a></li>' +
438 440 '<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' +
441 '<li class="heading2"><a href="#Subtitle-with-some-modifiers">Subtitle with some modifiers</a></li>' +
439 442 '<li class="heading1"><a href="#Another-title">Another title</a></li>' +
440 443 '<li class="heading2"><a href="#An-Internet-link-inside-subtitle">An Internet link inside subtitle</a></li>' +
441 444 '<li class="heading2"><a href="#Project-Name">Project Name</a></li>' +
442 445 '</ul>'
443 446
447 @project = Project.find(1)
448 assert textilizable(raw).gsub("\n", "").include?(expected)
449 end
450
451 def test_table_of_content_should_contain_included_page_headings
452 raw = <<-RAW
453 {{toc}}
454
455 h1. Included
456
457 {{include(Child_1)}}
458 RAW
459
460 expected = '<ul class="toc">' +
461 '<li class="heading1"><a href="#Included">Included</a></li>' +
462 '<li class="heading1"><a href="#Child-page-1">Child page 1</a></li>' +
463 '</ul>'
464
465 @project = Project.find(1)
444 466 assert textilizable(raw).gsub("\n", "").include?(expected)
445 467 end
446 468
@@ -20,6 +20,9 require File.dirname(__FILE__) + '/../../../../test_helper'
20 20 class Redmine::WikiFormatting::MacrosTest < HelperTestCase
21 21 include ApplicationHelper
22 22 include ActionView::Helpers::TextHelper
23 include ActionView::Helpers::SanitizeHelper
24 extend ActionView::Helpers::SanitizeHelper::ClassMethods
25
23 26 fixtures :projects, :roles, :enabled_modules, :users,
24 27 :repositories, :changesets,
25 28 :trackers, :issue_statuses, :issues,
General Comments 0
You need to be logged in to leave comments. Login now