summaryrefslogtreecommitdiffstats
path: root/lib/redmine/wiki_formatting
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2013-12-23 13:05:10 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2013-12-23 13:05:10 +0000
commit471e01ca5059f892888f78e2278dd41d742a4b75 (patch)
treea07ecd3d8911cf0e6ce1220584fa2c10ed81b9ab /lib/redmine/wiki_formatting
parent6311ade82708b63b83d30278a1af4c05af4aee6e (diff)
downloadredmine-471e01ca5059f892888f78e2278dd41d742a4b75.tar.gz
redmine-471e01ca5059f892888f78e2278dd41d742a4b75.zip
Adds experimental support for Markdown formatting with redcarpet (#15520).
git-svn-id: http://svn.redmine.org/redmine/trunk@12452 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'lib/redmine/wiki_formatting')
-rw-r--r--lib/redmine/wiki_formatting/markdown/formatter.rb136
-rw-r--r--lib/redmine/wiki_formatting/markdown/helper.rb45
2 files changed, 181 insertions, 0 deletions
diff --git a/lib/redmine/wiki_formatting/markdown/formatter.rb b/lib/redmine/wiki_formatting/markdown/formatter.rb
new file mode 100644
index 000000000..19ee46693
--- /dev/null
+++ b/lib/redmine/wiki_formatting/markdown/formatter.rb
@@ -0,0 +1,136 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+require 'cgi'
+
+module Redmine
+ module WikiFormatting
+ module Markdown
+ class HTML < Redcarpet::Render::HTML
+ include ActionView::Helpers::TagHelper
+
+ def link(link, title, content)
+ css = nil
+ unless link && link.starts_with?('/')
+ css = 'external'
+ end
+ content_tag('a', content.html_safe, :href => link, :title => title, :class => css)
+ end
+
+ def block_code(code, language)
+ if language.present?
+ "<pre><code class=\"#{CGI.escapeHTML language} syntaxhl\">" +
+ Redmine::SyntaxHighlighting.highlight_by_language(code, language) +
+ "</code></pre>"
+ else
+ "<pre>" + CGI.escapeHTML(code) + "</pre>"
+ end
+ end
+ end
+
+ class Formatter
+ def initialize(text)
+ @text = text
+ end
+
+ def to_html(*args)
+ html = formatter.render(@text)
+ # restore wiki links eg. [[Foo]]
+ html.gsub!(%r{\[<a href="(.*?)">(.*?)</a>\]}) do
+ "[[#{$2}]]"
+ end
+ # restore Redmine links with double-quotes, eg. version:"1.0"
+ html.gsub!(/(\w):&quot;(.+?)&quot;/) do
+ "#{$1}:\"#{$2}\""
+ end
+ html
+ end
+
+ def get_section(index)
+ section = extract_sections(index)[1]
+ hash = Digest::MD5.hexdigest(section)
+ return section, hash
+ end
+
+ def update_section(index, update, hash=nil)
+ t = extract_sections(index)
+ if hash.present? && hash != Digest::MD5.hexdigest(t[1])
+ raise Redmine::WikiFormatting::StaleSectionError
+ end
+ t[1] = update unless t[1].blank?
+ t.reject(&:blank?).join "\n\n"
+ end
+
+ def extract_sections(index)
+ sections = ['', '', '']
+ offset = 0
+ i = 0
+ l = 1
+ inside_pre = false
+ @text.split(/(^(?:.+\r?\n\r?(?:\=+|\-+)|#+.+|~~~.*)\s*$)/).each do |part|
+ level = nil
+ if part =~ /\A~{3,}(\S+)?\s*$/
+ if $1
+ if !inside_pre
+ inside_pre = true
+ end
+ else
+ inside_pre = !inside_pre
+ end
+ elsif inside_pre
+ # nop
+ elsif part =~ /\A(#+).+/
+ level = $1.size
+ elsif part =~ /\A.+\r?\n\r?(\=+|\-+)\s*$/
+ level = $1.include?('=') ? 1 : 2
+ end
+ if level
+ i += 1
+ if offset == 0 && i == index
+ # entering the requested section
+ offset = 1
+ l = level
+ elsif offset == 1 && i > index && level <= l
+ # leaving the requested section
+ offset = 2
+ end
+ end
+ sections[offset] << part
+ end
+ sections.map(&:strip)
+ end
+
+ private
+
+ def formatter
+ @@formatter ||= Redcarpet::Markdown.new(
+ Redmine::WikiFormatting::Markdown::HTML.new(
+ :filter_html => true,
+ :hard_wrap => true
+ ),
+ :autolink => true,
+ :fenced_code_blocks => true,
+ :space_after_headers => true,
+ :tables => true,
+ :strikethrough => true,
+ :superscript => true
+ )
+ end
+ end
+ end
+ end
+end
diff --git a/lib/redmine/wiki_formatting/markdown/helper.rb b/lib/redmine/wiki_formatting/markdown/helper.rb
new file mode 100644
index 000000000..2619cb71e
--- /dev/null
+++ b/lib/redmine/wiki_formatting/markdown/helper.rb
@@ -0,0 +1,45 @@
+# Redmine - project management software
+# Copyright (C) 2006-2013 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+module Redmine
+ module WikiFormatting
+ module Markdown
+ module Helper
+ def wikitoolbar_for(field_id)
+ heads_for_wiki_formatter
+ javascript_tag("var wikiToolbar = new jsToolBar(document.getElementById('#{field_id}')); wikiToolbar.draw();")
+ end
+
+ def initial_page_content(page)
+ "# #{@page.pretty_title}"
+ end
+
+ def heads_for_wiki_formatter
+ unless @heads_for_wiki_formatter_included
+ content_for :header_tags do
+ javascript_include_tag('jstoolbar/jstoolbar') +
+ javascript_include_tag('jstoolbar/markdown') +
+ javascript_include_tag("jstoolbar/lang/jstoolbar-#{current_language.to_s.downcase}") +
+ stylesheet_link_tag('jstoolbar')
+ end
+ @heads_for_wiki_formatter_included = true
+ end
+ end
+ end
+ end
+ end
+end