annotate lib/redmine/wiki_formatting.rb @ 8:0c83d98252d9 yuya

* Add custom repo prefix and proper auth realm, remove auth cache (seems like an unwise feature), pass DB handle around, various other bits of tidying
author Chris Cannam
date Thu, 12 Aug 2010 15:31:37 +0100
parents 513646585e45
children cbb26bc654de
rev   line source
Chris@0 1 # Redmine - project management software
Chris@0 2 # Copyright (C) 2006-2008 Jean-Philippe Lang
Chris@0 3 #
Chris@0 4 # This program is free software; you can redistribute it and/or
Chris@0 5 # modify it under the terms of the GNU General Public License
Chris@0 6 # as published by the Free Software Foundation; either version 2
Chris@0 7 # of the License, or (at your option) any later version.
Chris@0 8 #
Chris@0 9 # This program is distributed in the hope that it will be useful,
Chris@0 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 12 # GNU General Public License for more details.
Chris@0 13 #
Chris@0 14 # You should have received a copy of the GNU General Public License
Chris@0 15 # along with this program; if not, write to the Free Software
Chris@0 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Chris@0 17
Chris@0 18 module Redmine
Chris@0 19 module WikiFormatting
Chris@0 20 @@formatters = {}
Chris@0 21
Chris@0 22 class << self
Chris@0 23 def map
Chris@0 24 yield self
Chris@0 25 end
Chris@0 26
Chris@0 27 def register(name, formatter, helper)
Chris@0 28 raise ArgumentError, "format name '#{name}' is already taken" if @@formatters[name.to_s]
Chris@0 29 @@formatters[name.to_s] = {:formatter => formatter, :helper => helper}
Chris@0 30 end
Chris@0 31
Chris@0 32 def formatter_for(name)
Chris@0 33 entry = @@formatters[name.to_s]
Chris@0 34 (entry && entry[:formatter]) || Redmine::WikiFormatting::NullFormatter::Formatter
Chris@0 35 end
Chris@0 36
Chris@0 37 def helper_for(name)
Chris@0 38 entry = @@formatters[name.to_s]
Chris@0 39 (entry && entry[:helper]) || Redmine::WikiFormatting::NullFormatter::Helper
Chris@0 40 end
Chris@0 41
Chris@0 42 def format_names
Chris@0 43 @@formatters.keys.map
Chris@0 44 end
Chris@0 45
Chris@0 46 def to_html(format, text, options = {}, &block)
Chris@0 47 text = if Setting.cache_formatted_text? && text.size > 2.kilobyte && cache_store && cache_key = cache_key_for(format, options[:object], options[:attribute])
Chris@0 48 # Text retrieved from the cache store may be frozen
Chris@0 49 # We need to dup it so we can do in-place substitutions with gsub!
Chris@0 50 cache_store.fetch cache_key do
Chris@0 51 formatter_for(format).new(text).to_html
Chris@0 52 end.dup
Chris@0 53 else
Chris@0 54 formatter_for(format).new(text).to_html
Chris@0 55 end
Chris@0 56 if block_given?
Chris@0 57 execute_macros(text, block)
Chris@0 58 end
Chris@0 59 text
Chris@0 60 end
Chris@0 61
Chris@0 62 # Returns a cache key for the given text +format+, +object+ and +attribute+ or nil if no caching should be done
Chris@0 63 def cache_key_for(format, object, attribute)
Chris@0 64 if object && attribute && !object.new_record? && object.respond_to?(:updated_on) && !format.blank?
Chris@0 65 "formatted_text/#{format}/#{object.class.model_name.cache_key}/#{object.id}-#{attribute}-#{object.updated_on.to_s(:number)}"
Chris@0 66 end
Chris@0 67 end
Chris@0 68
Chris@0 69 # Returns the cache store used to cache HTML output
Chris@0 70 def cache_store
Chris@0 71 ActionController::Base.cache_store
Chris@0 72 end
Chris@0 73
Chris@0 74 MACROS_RE = /
Chris@0 75 (!)? # escaping
Chris@0 76 (
Chris@0 77 \{\{ # opening tag
Chris@0 78 ([\w]+) # macro name
Chris@0 79 (\(([^\}]*)\))? # optional arguments
Chris@0 80 \}\} # closing tag
Chris@0 81 )
Chris@0 82 /x unless const_defined?(:MACROS_RE)
Chris@0 83
Chris@0 84 # Macros substitution
Chris@0 85 def execute_macros(text, macros_runner)
Chris@0 86 text.gsub!(MACROS_RE) do
Chris@0 87 esc, all, macro = $1, $2, $3.downcase
Chris@0 88 args = ($5 || '').split(',').each(&:strip)
Chris@0 89 if esc.nil?
Chris@0 90 begin
Chris@0 91 macros_runner.call(macro, args)
Chris@0 92 rescue => e
Chris@0 93 "<div class=\"flash error\">Error executing the <strong>#{macro}</strong> macro (#{e})</div>"
Chris@0 94 end || all
Chris@0 95 else
Chris@0 96 all
Chris@0 97 end
Chris@0 98 end
Chris@0 99 end
Chris@0 100 end
Chris@0 101
Chris@0 102 # Default formatter module
Chris@0 103 module NullFormatter
Chris@0 104 class Formatter
Chris@0 105 include ActionView::Helpers::TagHelper
Chris@0 106 include ActionView::Helpers::TextHelper
Chris@0 107 include ActionView::Helpers::UrlHelper
Chris@0 108
Chris@0 109 def initialize(text)
Chris@0 110 @text = text
Chris@0 111 end
Chris@0 112
Chris@0 113 def to_html(*args)
Chris@0 114 simple_format(auto_link(CGI::escapeHTML(@text)))
Chris@0 115 end
Chris@0 116 end
Chris@0 117
Chris@0 118 module Helper
Chris@0 119 def wikitoolbar_for(field_id)
Chris@0 120 end
Chris@0 121
Chris@0 122 def heads_for_wiki_formatter
Chris@0 123 end
Chris@0 124
Chris@0 125 def initial_page_content(page)
Chris@0 126 page.pretty_title.to_s
Chris@0 127 end
Chris@0 128 end
Chris@0 129 end
Chris@0 130 end
Chris@0 131 end