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 |
142 |
args = ($5 || '').split(',').each(&: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{
|