diff --git a/app/helpers/redmine_markdown_extra_formatter/helper.rb b/app/helpers/redmine_markdown_extra_formatter/helper.rb index 353ae07..65bfbe0 100644 --- a/app/helpers/redmine_markdown_extra_formatter/helper.rb +++ b/app/helpers/redmine_markdown_extra_formatter/helper.rb @@ -3,8 +3,7 @@ module Helper unloadable def wikitoolbar_for(field_id) - url = Redmine::Utils.relative_url_root + - Engines::RailsExtensions::AssetHelpers.plugin_asset_path('redmine_markdown_extra_formatter', 'help', 'markdown_extra_syntax.html') + url = Engines::RailsExtensions::AssetHelpers.plugin_asset_path('redmine_markdown_extra_formatter', 'help', 'markdown_extra_syntax.html') help_link = l(:setting_text_formatting) + ': ' + link_to(l(:label_help), url, :onclick => "window.open(\"#{url}\", \"\", \"resizable=yes, location=no, width=300, height=640, menubar=no, status=no, scrollbars=yes\"); return false;") diff --git a/assets/help/markdown_extra_syntax.html b/assets/help/markdown_extra_syntax.html index 1471415..cd47d74 100644 --- a/assets/help/markdown_extra_syntax.html +++ b/assets/help/markdown_extra_syntax.html @@ -43,7 +43,7 @@

Wiki Syntax Quick Reference

Underline - <ins>Underline</ins>> + <ins>Underline</ins> Underline @@ -54,7 +54,7 @@

Wiki Syntax Quick Reference

- </cite>Quote</cite> + <cite>Quote</cite> Quote diff --git a/lib/redmine_markdown_extra_formatter/wiki_formatter.rb b/lib/redmine_markdown_extra_formatter/wiki_formatter.rb index 6d181f7..9254d61 100644 --- a/lib/redmine_markdown_extra_formatter/wiki_formatter.rb +++ b/lib/redmine_markdown_extra_formatter/wiki_formatter.rb @@ -93,14 +93,51 @@ def transform_toc( str, rs ) module RedmineMarkdownExtraFormatter class WikiFormatter + include ActionView::Helpers::TagHelper + def initialize(text) @text = text end + # Taken from + # https://github.com/github/github-flavored-markdown/blob/gh-pages/code.rb, + # with modifications. + def gfm(text) + # Extract pre blocks + extractions = {} + text.gsub!(%r{
.*?
|(?:(?: |\t)[^\n]*\n)+}m) do |match| + md5 = Digest::MD5.hexdigest(match) + extractions[md5] = match + "{gfm-extraction-#{md5}}" + end + + # escape underline characters that aren't on a word boundary + text.gsub!(%r{([^\s_]+\w+[^\s_]+)}) { |x| x.gsub('_', '\_') } + + # in very clear cases, let newlines become
tags + text.gsub!(/(\A|^$\n)(^\w[^\n]*\n)(^\w[^\n]*$)+/m) do |x| + x.gsub(/^(.+)$/, "\\1 ") + end + + # Insert pre block extractions + text.gsub!(/\{gfm-extraction-([0-9a-f]{32})\}/) do + extractions[$1] + end + + + puts "\n\n\n#{text.inspect}\n\n\n" + + text + end + def to_html(&block) @macros_runner = block - parsedText = BlueFeather.parse(@text) - parsedText = inline_macros(parsedText) + parsedText = @text.dup + parsedText.gsub!("\r\n", "\n") + parsedText = gfm(parsedText) + parsedText = BlueFeather.parse(parsedText) + parsedText = inline_auto_link(parsedText) + parsedText = inline_auto_mailto(parsedText) parsedText = syntax_highlight(parsedText) rescue => e return("
problem parsing wiki text: #{e.message}\n"+
@@ -109,33 +146,6 @@ def to_html(&block)
              "
") end - MACROS_RE = / - (!)? # escaping - ( - \{\{ # opening tag - ([\w]+) # macro name - (\(([^\}]*)\))? # optional arguments - \}\} # closing tag - ) - /x - - def inline_macros(text) - text.gsub!(MACROS_RE) do - esc, all, macro = $1, $2, $3.downcase - args = ($5 || '').split(',').each(&:strip) - if esc.nil? - begin - @macros_runner.call(macro, args) - rescue => e - "
Error executing the #{macro} macro (#{e})
" - end || all - else - all - end - end - text - end - PreCodeClassBlockRegexp = %r{^
\s*\n*(.+?)
}m def syntax_highlight(str) @@ -146,5 +156,59 @@ def syntax_highlight(str) "" } end + + AUTO_LINK_RE = %r{ + ( # leading text + <\w+.*?>| # leading HTML tag, or + [^=<>!:'"/]| # leading punctuation, or + ^ # beginning of line + ) + ( + (?:https?://)| # protocol spec, or + (?:s?ftps?://)| + (?:www\.) # www.* + ) + ( + (\S+?) # url + (\/)? # slash + ) + ((?:>)?|[^\w\=\/;\(\)]*?) # post + (?=<|\s|$) + }x unless const_defined?(:AUTO_LINK_RE) + + # Turns all urls into clickable links (code from Rails). + def inline_auto_link(text) + text.gsub!(AUTO_LINK_RE) do + all, leading, proto, url, post = $&, $1, $2, $3, $6 + if leading =~ /=]?/ + # don't replace URL's that are already linked + # and URL's prefixed with ! !> !< != (textile images) + all + else + # Idea below : an URL with unbalanced parethesis and + # ending by ')' is put into external parenthesis + if ( url[-1]==?) and ((url.count("(") - url.count(")")) < 0 ) ) + url=url[0..-2] # discard closing parenth from url + post = ")"+post # add closing parenth to post + end + tag = content_tag('a', proto + url, :href => "#{proto=="www."?"http://www.":proto}#{url}", :class => 'external') + %(#{leading}#{tag}#{post}) + end + end + text + end + + # Turns all email addresses into clickable links (code from Rails). + def inline_auto_mailto(text) + text.gsub!(/([\w\.!#\$%\-+.]+@[A-Za-z0-9\-]+(\.[A-Za-z0-9\-]+)+)/) do + mail = $1 + if text.match(/]*>(.*)(#{Regexp.escape(mail)})(.*)<\/a>/) + mail + else + content_tag('a', mail, :href => "mailto:#{mail}", :class => "email") + end + end + text + end end end