To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.
root / lib / redmine / wiki_formatting / macros.rb @ 912:5e80956cc792
History | View | Annotate | Download (4.78 KB)
| 1 | 909:cbb26bc654de | Chris | # Redmine - project management software
|
|---|---|---|---|
| 2 | # Copyright (C) 2006-2011 Jean-Philippe Lang
|
||
| 3 | 0:513646585e45 | Chris | #
|
| 4 | # This program is free software; you can redistribute it and/or
|
||
| 5 | # modify it under the terms of the GNU General Public License
|
||
| 6 | # as published by the Free Software Foundation; either version 2
|
||
| 7 | # of the License, or (at your option) any later version.
|
||
| 8 | 909:cbb26bc654de | Chris | #
|
| 9 | 0:513646585e45 | Chris | # This program is distributed in the hope that it will be useful,
|
| 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
| 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
| 12 | # GNU General Public License for more details.
|
||
| 13 | 909:cbb26bc654de | Chris | #
|
| 14 | 0:513646585e45 | Chris | # You should have received a copy of the GNU General Public License
|
| 15 | # along with this program; if not, write to the Free Software
|
||
| 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||
| 17 | |||
| 18 | module Redmine |
||
| 19 | module WikiFormatting |
||
| 20 | module Macros |
||
| 21 | module Definitions |
||
| 22 | def exec_macro(name, obj, args) |
||
| 23 | method_name = "macro_#{name}"
|
||
| 24 | send(method_name, obj, args) if respond_to?(method_name)
|
||
| 25 | end
|
||
| 26 | 909:cbb26bc654de | Chris | |
| 27 | 0:513646585e45 | Chris | def extract_macro_options(args, *keys) |
| 28 | options = {}
|
||
| 29 | while args.last.to_s.strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym) |
||
| 30 | options[$1.downcase.to_sym] = $2 |
||
| 31 | args.pop |
||
| 32 | end
|
||
| 33 | return [args, options]
|
||
| 34 | end
|
||
| 35 | end
|
||
| 36 | 909:cbb26bc654de | Chris | |
| 37 | 0:513646585e45 | Chris | @@available_macros = {}
|
| 38 | 909:cbb26bc654de | Chris | |
| 39 | 0:513646585e45 | Chris | class << self |
| 40 | # Called with a block to define additional macros.
|
||
| 41 | # Macro blocks accept 2 arguments:
|
||
| 42 | # * obj: the object that is rendered
|
||
| 43 | # * args: macro arguments
|
||
| 44 | 909:cbb26bc654de | Chris | #
|
| 45 | 0:513646585e45 | Chris | # Plugins can use this method to define new macros:
|
| 46 | 909:cbb26bc654de | Chris | #
|
| 47 | 0:513646585e45 | Chris | # Redmine::WikiFormatting::Macros.register do
|
| 48 | # desc "This is my macro"
|
||
| 49 | # macro :my_macro do |obj, args|
|
||
| 50 | # "My macro output"
|
||
| 51 | # end
|
||
| 52 | # end
|
||
| 53 | def register(&block) |
||
| 54 | class_eval(&block) if block_given?
|
||
| 55 | end
|
||
| 56 | 909:cbb26bc654de | Chris | |
| 57 | 0:513646585e45 | Chris | private |
| 58 | # Defines a new macro with the given name and block.
|
||
| 59 | def macro(name, &block) |
||
| 60 | name = name.to_sym if name.is_a?(String) |
||
| 61 | @@available_macros[name] = @@desc || '' |
||
| 62 | @@desc = nil |
||
| 63 | raise "Can not create a macro without a block!" unless block_given? |
||
| 64 | Definitions.send :define_method, "macro_#{name}".downcase, &block |
||
| 65 | end
|
||
| 66 | 909:cbb26bc654de | Chris | |
| 67 | 0:513646585e45 | Chris | # Sets description for the next macro to be defined
|
| 68 | def desc(txt) |
||
| 69 | @@desc = txt
|
||
| 70 | end
|
||
| 71 | end
|
||
| 72 | 909:cbb26bc654de | Chris | |
| 73 | 0:513646585e45 | Chris | # Builtin macros
|
| 74 | desc "Sample macro."
|
||
| 75 | macro :hello_world do |obj, args| |
||
| 76 | "Hello world! Object: #{obj.class.name}, " + (args.empty? ? "Called with no argument." : "Arguments: #{args.join(', ')}") |
||
| 77 | end
|
||
| 78 | 909:cbb26bc654de | Chris | |
| 79 | 0:513646585e45 | Chris | desc "Displays a list of all available macros, including description if available."
|
| 80 | 909:cbb26bc654de | Chris | macro :macro_list do |obj, args| |
| 81 | 0:513646585e45 | Chris | out = ''
|
| 82 | @@available_macros.keys.collect(&:to_s).sort.each do |macro| |
||
| 83 | out << content_tag('dt', content_tag('code', macro)) |
||
| 84 | out << content_tag('dd', textilizable(@@available_macros[macro.to_sym])) |
||
| 85 | end
|
||
| 86 | content_tag('dl', out)
|
||
| 87 | end
|
||
| 88 | 909:cbb26bc654de | Chris | |
| 89 | 0:513646585e45 | Chris | desc "Displays a list of child pages. With no argument, it displays the child pages of the current wiki page. Examples:\n\n" +
|
| 90 | " !{{child_pages}} -- can be used from a wiki page only\n" +
|
||
| 91 | " !{{child_pages(Foo)}} -- lists all children of page Foo\n" +
|
||
| 92 | " !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo"
|
||
| 93 | macro :child_pages do |obj, args| |
||
| 94 | args, options = extract_macro_options(args, :parent)
|
||
| 95 | page = nil
|
||
| 96 | if args.size > 0 |
||
| 97 | page = Wiki.find_page(args.first.to_s, :project => @project) |
||
| 98 | elsif obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version) |
||
| 99 | page = obj.page |
||
| 100 | else
|
||
| 101 | raise 'With no argument, this macro can be called from wiki pages only.'
|
||
| 102 | end
|
||
| 103 | raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) |
||
| 104 | pages = ([page] + page.descendants).group_by(&:parent_id)
|
||
| 105 | render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id)
|
||
| 106 | end
|
||
| 107 | 909:cbb26bc654de | Chris | |
| 108 | 0:513646585e45 | Chris | 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)}}"
|
| 109 | macro :include do |obj, args| |
||
| 110 | page = Wiki.find_page(args.first.to_s, :project => @project) |
||
| 111 | raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) |
||
| 112 | @included_wiki_pages ||= []
|
||
| 113 | raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title) |
||
| 114 | @included_wiki_pages << page.title
|
||
| 115 | 37:94944d00e43c | chris | out = textilizable(page.content, :text, :attachments => page.attachments, :headings => false) |
| 116 | 0:513646585e45 | Chris | @included_wiki_pages.pop
|
| 117 | out |
||
| 118 | end
|
||
| 119 | end
|
||
| 120 | end
|
||
| 121 | end |