Mercurial > hg > soundsoftware-site
diff lib/redmine/wiki_formatting/.svn/text-base/macros.rb.svn-base @ 0:513646585e45
* Import Redmine trunk SVN rev 3859
author | Chris Cannam |
---|---|
date | Fri, 23 Jul 2010 15:52:44 +0100 |
parents | |
children | 94944d00e43c |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/redmine/wiki_formatting/.svn/text-base/macros.rb.svn-base Fri Jul 23 15:52:44 2010 +0100 @@ -0,0 +1,121 @@ +# redMine - project management software +# Copyright (C) 2006-2007 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +module Redmine + module WikiFormatting + module Macros + module Definitions + def exec_macro(name, obj, args) + method_name = "macro_#{name}" + send(method_name, obj, args) if respond_to?(method_name) + end + + def extract_macro_options(args, *keys) + options = {} + while args.last.to_s.strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym) + options[$1.downcase.to_sym] = $2 + args.pop + end + return [args, options] + end + end + + @@available_macros = {} + + class << self + # Called with a block to define additional macros. + # Macro blocks accept 2 arguments: + # * obj: the object that is rendered + # * args: macro arguments + # + # Plugins can use this method to define new macros: + # + # Redmine::WikiFormatting::Macros.register do + # desc "This is my macro" + # macro :my_macro do |obj, args| + # "My macro output" + # end + # end + def register(&block) + class_eval(&block) if block_given? + end + + private + # Defines a new macro with the given name and block. + def macro(name, &block) + name = name.to_sym if name.is_a?(String) + @@available_macros[name] = @@desc || '' + @@desc = nil + raise "Can not create a macro without a block!" unless block_given? + Definitions.send :define_method, "macro_#{name}".downcase, &block + end + + # Sets description for the next macro to be defined + def desc(txt) + @@desc = txt + end + end + + # Builtin macros + desc "Sample macro." + macro :hello_world do |obj, args| + "Hello world! Object: #{obj.class.name}, " + (args.empty? ? "Called with no argument." : "Arguments: #{args.join(', ')}") + end + + desc "Displays a list of all available macros, including description if available." + macro :macro_list do + out = '' + @@available_macros.keys.collect(&:to_s).sort.each do |macro| + out << content_tag('dt', content_tag('code', macro)) + out << content_tag('dd', textilizable(@@available_macros[macro.to_sym])) + end + content_tag('dl', out) + end + + desc "Displays a list of child pages. With no argument, it displays the child pages of the current wiki page. Examples:\n\n" + + " !{{child_pages}} -- can be used from a wiki page only\n" + + " !{{child_pages(Foo)}} -- lists all children of page Foo\n" + + " !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo" + macro :child_pages do |obj, args| + args, options = extract_macro_options(args, :parent) + page = nil + if args.size > 0 + page = Wiki.find_page(args.first.to_s, :project => @project) + elsif obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version) + page = obj.page + else + raise 'With no argument, this macro can be called from wiki pages only.' + end + raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) + pages = ([page] + page.descendants).group_by(&:parent_id) + render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id) + end + + desc "Include a wiki page. Example:\n\n !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n !{{include(projectname:Foo)}}" + macro :include do |obj, args| + page = Wiki.find_page(args.first.to_s, :project => @project) + raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) + @included_wiki_pages ||= [] + raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title) + @included_wiki_pages << page.title + out = textilizable(page.content, :text, :attachments => page.attachments) + @included_wiki_pages.pop + out + end + end + end +end