##// END OF EJS Templates
Enables footnote support with Markdown (#16072)....
Jean-Philippe Lang -
r14246:dfa69b2eb0f8
parent child
Show More
@@ -1,137 +1,138
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2015 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
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'cgi'
19 19
20 20 module Redmine
21 21 module WikiFormatting
22 22 module Markdown
23 23 class HTML < Redcarpet::Render::HTML
24 24 include ActionView::Helpers::TagHelper
25 25
26 26 def link(link, title, content)
27 27 css = nil
28 28 unless link && link.starts_with?('/')
29 29 css = 'external'
30 30 end
31 31 content_tag('a', content.to_s.html_safe, :href => link, :title => title, :class => css)
32 32 end
33 33
34 34 def block_code(code, language)
35 35 if language.present?
36 36 "<pre><code class=\"#{CGI.escapeHTML language} syntaxhl\">" +
37 37 Redmine::SyntaxHighlighting.highlight_by_language(code, language) +
38 38 "</code></pre>"
39 39 else
40 40 "<pre>" + CGI.escapeHTML(code) + "</pre>"
41 41 end
42 42 end
43 43 end
44 44
45 45 class Formatter
46 46 def initialize(text)
47 47 @text = text
48 48 end
49 49
50 50 def to_html(*args)
51 51 html = formatter.render(@text)
52 52 # restore wiki links eg. [[Foo]]
53 53 html.gsub!(%r{\[<a href="(.*?)">(.*?)</a>\]}) do
54 54 "[[#{$2}]]"
55 55 end
56 56 # restore Redmine links with double-quotes, eg. version:"1.0"
57 57 html.gsub!(/(\w):&quot;(.+?)&quot;/) do
58 58 "#{$1}:\"#{$2}\""
59 59 end
60 60 html
61 61 end
62 62
63 63 def get_section(index)
64 64 section = extract_sections(index)[1]
65 65 hash = Digest::MD5.hexdigest(section)
66 66 return section, hash
67 67 end
68 68
69 69 def update_section(index, update, hash=nil)
70 70 t = extract_sections(index)
71 71 if hash.present? && hash != Digest::MD5.hexdigest(t[1])
72 72 raise Redmine::WikiFormatting::StaleSectionError
73 73 end
74 74 t[1] = update unless t[1].blank?
75 75 t.reject(&:blank?).join "\n\n"
76 76 end
77 77
78 78 def extract_sections(index)
79 79 sections = ['', '', '']
80 80 offset = 0
81 81 i = 0
82 82 l = 1
83 83 inside_pre = false
84 84 @text.split(/(^(?:.+\r?\n\r?(?:\=+|\-+)|#+.+|~~~.*)\s*$)/).each do |part|
85 85 level = nil
86 86 if part =~ /\A~{3,}(\S+)?\s*$/
87 87 if $1
88 88 if !inside_pre
89 89 inside_pre = true
90 90 end
91 91 else
92 92 inside_pre = !inside_pre
93 93 end
94 94 elsif inside_pre
95 95 # nop
96 96 elsif part =~ /\A(#+).+/
97 97 level = $1.size
98 98 elsif part =~ /\A.+\r?\n\r?(\=+|\-+)\s*$/
99 99 level = $1.include?('=') ? 1 : 2
100 100 end
101 101 if level
102 102 i += 1
103 103 if offset == 0 && i == index
104 104 # entering the requested section
105 105 offset = 1
106 106 l = level
107 107 elsif offset == 1 && i > index && level <= l
108 108 # leaving the requested section
109 109 offset = 2
110 110 end
111 111 end
112 112 sections[offset] << part
113 113 end
114 114 sections.map(&:strip)
115 115 end
116 116
117 117 private
118 118
119 119 def formatter
120 120 @@formatter ||= Redcarpet::Markdown.new(
121 121 Redmine::WikiFormatting::Markdown::HTML.new(
122 122 :filter_html => true,
123 123 :hard_wrap => true
124 124 ),
125 125 :autolink => true,
126 126 :fenced_code_blocks => true,
127 127 :space_after_headers => true,
128 128 :tables => true,
129 129 :strikethrough => true,
130 130 :superscript => true,
131 :no_intra_emphasis => true
131 :no_intra_emphasis => true,
132 :footnotes => true
132 133 )
133 134 end
134 135 end
135 136 end
136 137 end
137 138 end
General Comments 0
You need to be logged in to leave comments. Login now