| 17 | 17 |  | 
  | 18 | 18 | require 'redcloth3' | 
  | 19 | 19 | require 'coderay' | 
  |  | 20 | require 'digest/md5' | 
  | 20 | 21 |  | 
  | 21 | 22 | module Redmine | 
  | 22 | 23 |   module WikiFormatting | 
  | ... | ... |  | 
  | 37 | 38 |         def to_html(*rules, &block) | 
  | 38 | 39 |           @toc = [] | 
  | 39 | 40 |           @macros_runner = block | 
  |  | 41 |           preprocess_inline_macros self  # FIXME: silly to edit self | 
  | 40 | 42 |           super(*RULES).to_s | 
  | 41 | 43 |         end | 
  | 42 | 44 |    | 
  | ... | ... |  | 
  | 113 | 115 |                       ( | 
  | 114 | 116 |                       \{\{                        # opening tag | 
  | 115 | 117 |                       ([\w]+)                     # macro name | 
  | 116 |  |                       (\(([^\}]*)\))?             # optional arguments | 
  |  | 118 |                       (\((.*?)\))?                # optional arguments | 
  | 117 | 119 |                       \}\}                        # closing tag | 
  | 118 | 120 |                       ) | 
  | 119 |  |                     /x unless const_defined?(:MACROS_RE) | 
  |  | 121 |                     /xm unless const_defined?(:MACROS_RE) | 
  | 120 | 122 |          | 
  |  | 123 |         # grab raw text for wiki_external_filter macro | 
  |  | 124 |         def preprocess_inline_macros(text) | 
  |  | 125 |           @inline_macros_grabbed = {} | 
  |  | 126 |           text.gsub!(MACROS_RE) do |s| | 
  |  | 127 |             esc, all, macro = $1, $2, $3.downcase | 
  |  | 128 |             if esc.nil? and (WikiExternalFilterHelper.has_macro macro rescue false) | 
  |  | 129 |               args = $5 | 
  |  | 130 |               key = Digest::MD5.hexdigest("#{macro}:#{args}") | 
  |  | 131 |               @inline_macros_grabbed[key] = {:macro => macro, :args => args} | 
  |  | 132 |               "{{_inline_macros_grabbed(#{key})}}" | 
  |  | 133 |             else | 
  |  | 134 |               s | 
  |  | 135 |             end | 
  |  | 136 |           end | 
  |  | 137 |         end | 
  |  | 138 |  | 
  | 121 | 139 |         def inline_macros(text) | 
  | 122 | 140 |           text.gsub!(MACROS_RE) do | 
  | 123 | 141 |             esc, all, macro = $1, $2, $3.downcase | 
  | 124 |  |             args = ($5 || '').split(',').each(&:strip) | 
  |  | 142 |             args = ($5 || '').split(',').map(&:strip) | 
  |  | 143 |             if macro == '_inline_macros_grabbed' and @inline_macros_grabbed.member? args.first | 
  |  | 144 |               macro, args = @inline_macros_grabbed[args.first].values_at(:macro, :args) | 
  |  | 145 |             end | 
  | 125 | 146 |             if esc.nil? | 
  | 126 | 147 |               begin | 
  | 127 | 148 |                 @macros_runner.call(macro, args) | 
  | ... | ... |  | 
  | 132 | 153 |               all | 
  | 133 | 154 |             end | 
  | 134 | 155 |           end | 
  |  | 156 |         ensure | 
  |  | 157 |           @inline_macros_grabbed.clear | 
  | 135 | 158 |         end | 
  | 136 | 159 |          | 
  | 137 | 160 |         AUTO_LINK_RE = %r{ |