# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1279556285 -32400
# Branch 0.9-stable
# Node ID d9ca40844a310f61142b1154b4263ba25aa5ec42
# Parent  dd3224857dd9ba385e7298cc58e780ae04f32fb6
wiki: textile: workaround for redmine_wiki_external_filter

 * multiline macro support
 * grab macro text before passing to textile processor

diff --git a/lib/redmine/wiki_formatting/textile/formatter.rb b/lib/redmine/wiki_formatting/textile/formatter.rb
--- a/lib/redmine/wiki_formatting/textile/formatter.rb
+++ b/lib/redmine/wiki_formatting/textile/formatter.rb
@@ -17,6 +17,7 @@
 
 require 'redcloth3'
 require 'coderay'
+require 'digest/md5'
 
 module Redmine
   module WikiFormatting
@@ -37,6 +38,7 @@ module Redmine
         def to_html(*rules, &block)
           @toc = []
           @macros_runner = block
+          preprocess_inline_macros self  # FIXME: silly to edit self
           super(*RULES).to_s
         end
   
@@ -113,15 +115,34 @@ module Redmine
                       (
                       \{\{                        # opening tag
                       ([\w]+)                     # macro name
-                      (\(([^\}]*)\))?             # optional arguments
+                      (\((.*?)\))?                # optional arguments
                       \}\}                        # closing tag
                       )
-                    /x unless const_defined?(:MACROS_RE)
+                    /xm unless const_defined?(:MACROS_RE)
         
+        # grab raw text for wiki_external_filter macro
+        def preprocess_inline_macros(text)
+          @inline_macros_grabbed = {}
+          text.gsub!(MACROS_RE) do |s|
+            esc, all, macro = $1, $2, $3.downcase
+            if esc.nil? and (WikiExternalFilterHelper.has_macro macro rescue false)
+              args = $5
+              key = Digest::MD5.hexdigest("#{macro}:#{args}")
+              @inline_macros_grabbed[key] = {:macro => macro, :args => args}
+              "{{_inline_macros_grabbed(#{key})}}"
+            else
+              s
+            end
+          end
+        end
+
         def inline_macros(text)
           text.gsub!(MACROS_RE) do
             esc, all, macro = $1, $2, $3.downcase
             args = ($5 || '').split(',').each(&:strip)
+            if macro == '_inline_macros_grabbed' and @inline_macros_grabbed.member? args.first
+              macro, args = @inline_macros_grabbed[args.first].values_at(:macro, :args)
+            end
             if esc.nil?
               begin
                 @macros_runner.call(macro, args)
@@ -132,6 +153,8 @@ module Redmine
               all
             end
           end
+        ensure
+          @inline_macros_grabbed.clear
         end
         
         AUTO_LINK_RE = %r{
