- Unified block/inline rendering.
- Split views to separate files. - Added PNG fallback for SVG displaying. - Improved SVG compliance.
This commit is contained in:
parent
8cfa874772
commit
5a6f81888f
|
@ -2,8 +2,13 @@ Redmine Wiki External Filter plugin that allows to filter macro blocks
|
||||||
arguments using external program and display results on wiki.
|
arguments using external program and display results on wiki.
|
||||||
|
|
||||||
Copyright (C) 2010 Alexander Tsvyashchenko, http://www.ndl.kiev.ua
|
Copyright (C) 2010 Alexander Tsvyashchenko, http://www.ndl.kiev.ua
|
||||||
Based on wiki_latex_plugin by Nils Israel <info@nils-israel.net>
|
|
||||||
Based on wiki_graphviz_plugin by tckz <at.tckz@gmail.com>
|
* Based on wiki_latex_plugin by Nils Israel <info@nils-israel.net>
|
||||||
|
* Based on wiki_graphviz_plugin by tckz <at.tckz@gmail.com>
|
||||||
|
* Includes FlowPlayer flash player, see http://www.flowplayer.org
|
||||||
|
* Includes CSS Browser Selector, see http://rafael.adm.br/css_browser_selector/
|
||||||
|
* Thanks to Eike for his "Cross-Browser SVG Issues" article,
|
||||||
|
http://e.metaclarity.org/52/cross-browser-svg-issues/
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -13,7 +13,7 @@ class WikiExternalFilterController < ApplicationController
|
||||||
content = read_fragment cache_key
|
content = read_fragment cache_key
|
||||||
|
|
||||||
if (content)
|
if (content)
|
||||||
send_data content[index], :type => config[macro]['content_type'], :disposition => 'inline', :filename => filename
|
send_data content[index], :type => config[macro]['outputs'][index]['content_type'], :disposition => 'inline', :filename => filename
|
||||||
else
|
else
|
||||||
render_404
|
render_404
|
||||||
end
|
end
|
||||||
|
|
|
@ -47,7 +47,6 @@ module WikiExternalFilterHelper
|
||||||
if content
|
if content
|
||||||
result[:source] = text
|
result[:source] = text
|
||||||
result[:content] = content
|
result[:content] = content
|
||||||
result[:content_type] = info['content_type']
|
|
||||||
RAILS_DEFAULT_LOGGER.debug "from cache: #{name}"
|
RAILS_DEFAULT_LOGGER.debug "from cache: #{name}"
|
||||||
else
|
else
|
||||||
result = self.build_forced(text, attachments, info)
|
result = self.build_forced(text, attachments, info)
|
||||||
|
@ -63,6 +62,8 @@ module WikiExternalFilterHelper
|
||||||
|
|
||||||
result[:name] = name
|
result[:name] = name
|
||||||
result[:macro] = macro
|
result[:macro] = macro
|
||||||
|
result[:content_types] = info['outputs'].map { |out| out['content_type'] }
|
||||||
|
result[:template] = info['template']
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
@ -79,18 +80,16 @@ module WikiExternalFilterHelper
|
||||||
content = []
|
content = []
|
||||||
errors = ""
|
errors = ""
|
||||||
|
|
||||||
commands = info['commands']? info['commands'] : [info['command']]
|
info['outputs'].each do |out|
|
||||||
|
RAILS_DEFAULT_LOGGER.info "executing command: #{out['command']}"
|
||||||
commands.each do |command|
|
|
||||||
RAILS_DEFAULT_LOGGER.info "executing command: #{command}"
|
|
||||||
|
|
||||||
c = nil
|
c = nil
|
||||||
e = nil
|
e = nil
|
||||||
|
|
||||||
Open4::popen4(command) { |pid, fin, fout, ferr|
|
Open4::popen4(out['command']) { |pid, fin, fout, ferr|
|
||||||
fin.write info[:prolog] if info.key?(:prolog)
|
fin.write out['prolog'] if out.key?('prolog')
|
||||||
fin.write CGI.unescapeHTML(text)
|
fin.write CGI.unescapeHTML(text)
|
||||||
fin.write info[:epilog] if info.key?(:epilog)
|
fin.write out['epilog'] if out.key?('epilog')
|
||||||
fin.close
|
fin.close
|
||||||
c, e = [fout.read, ferr.read]
|
c, e = [fout.read, ferr.read]
|
||||||
}
|
}
|
||||||
|
@ -103,7 +102,6 @@ module WikiExternalFilterHelper
|
||||||
|
|
||||||
result[:content] = content
|
result[:content] = content
|
||||||
result[:errors] = errors
|
result[:errors] = errors
|
||||||
result[:content_type] = info['content_type']
|
|
||||||
result[:source] = text
|
result[:source] = text
|
||||||
result[:status] = $?.exitstatus == 0
|
result[:status] = $?.exitstatus == 0
|
||||||
|
|
||||||
|
@ -111,21 +109,35 @@ module WikiExternalFilterHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_tag(result)
|
def render_tag(result)
|
||||||
render_to_string :template => 'wiki_external_filter/macro_inline', :layout => false, :locals => result
|
result = result.dup
|
||||||
|
result[:render_type] = 'inline'
|
||||||
|
html = render_common(result).chop
|
||||||
|
html << headers_common(result).chop
|
||||||
|
html
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_block(result, wiki_name)
|
def render_block(result, wiki_name)
|
||||||
result = result.dup
|
result = result.dup
|
||||||
|
result[:render_type] = 'block'
|
||||||
result[:wiki_name] = wiki_name
|
result[:wiki_name] = wiki_name
|
||||||
render_to_string :template => 'wiki_external_filter/macro_block', :layout => false, :locals => result
|
result[:inside] = render_common(result)
|
||||||
|
html = render_to_string(:template => 'wiki_external_filter/block', :layout => false, :locals => result).chop
|
||||||
|
html << headers_common(result).chop
|
||||||
|
html
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_common(result)
|
||||||
|
render_to_string :template => "wiki_external_filter/macro_#{result[:template]}", :layout => false, :locals => result
|
||||||
|
end
|
||||||
|
|
||||||
|
def headers_common(result)
|
||||||
|
render_to_string :template => 'wiki_external_filter/headers', :layout => false, :locals => result
|
||||||
end
|
end
|
||||||
|
|
||||||
class Macro
|
class Macro
|
||||||
def initialize(view, source, attachments, macro, info)
|
def initialize(view, source, attachments, macro, info)
|
||||||
@view = view
|
@view = view
|
||||||
@view.controller.extend(WikiExternalFilterHelper)
|
@view.controller.extend(WikiExternalFilterHelper)
|
||||||
source.gsub!(/<br \/>/, "")
|
|
||||||
source.gsub!(/<\/?p>/, "")
|
|
||||||
@result = @view.controller.build(source, attachments, macro, info)
|
@result = @view.controller.build(source, attachments, macro, info)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<div class='externalfilterblock'>
|
||||||
|
<%= inside %>
|
||||||
|
<br/>
|
||||||
|
<span class='wiki_page'>Goto source: [[<%= wiki_name %>]]</span>
|
||||||
|
</div>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<%
|
||||||
|
content_for :header_tags do
|
||||||
|
if not @stylesheets_included
|
||||||
|
@stylesheets_included = true
|
||||||
|
%>
|
||||||
|
<%= stylesheet_link_tag "wiki_external_filter.css", :plugin => "wiki_external_filter", :media => :all %>
|
||||||
|
<%
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%>
|
|
@ -1,64 +0,0 @@
|
||||||
<div class='externalfilterblock'>
|
|
||||||
<%
|
|
||||||
case content_type
|
|
||||||
when /image\// then
|
|
||||||
%>
|
|
||||||
<img src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name) %>' alt="<%= h source %>" />
|
|
||||||
<%
|
|
||||||
when /text\/plain/ then
|
|
||||||
%>
|
|
||||||
<pre><%= h content %></pre>
|
|
||||||
<%
|
|
||||||
when /\/.*(x|ht)ml/ then
|
|
||||||
%>
|
|
||||||
<div><%= content %></div>
|
|
||||||
<%
|
|
||||||
when /video\/x\-flv/ then
|
|
||||||
require 'RMagick'
|
|
||||||
image = Magick::Image::from_blob(content[0]).first
|
|
||||||
%>
|
|
||||||
<a class='flowplayer-video' href='<%= ActionController::Base.relative_url_root + "/wiki_external_filter/video.flv?name=#{name}" %>' alt='<%= h source %>' style='display:block;width:<%= image.columns %>px;height:<%= image.rows + 24 %>px;background-image:url(<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>);background-repeat:no-repeat'><%= image_tag 'play_large.png', :plugin => 'wiki_external_filter', :style => "display:block;position:relative;left:#{image.columns / 2 - 83 / 2}px;top:#{image.rows / 2 - 83 / 2}px" %></a>
|
|
||||||
<%
|
|
||||||
@flowplayer_used = true
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
else
|
|
||||||
%>
|
|
||||||
<object class='externalfilterinline' name='<%= name %>' data='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name) %>' type='<%= content_type %>' title="<%= h source %>">
|
|
||||||
<embed name='<%= name %>-2' src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name) %>' type='<%= content_type %>' title="<%= h source %>" />
|
|
||||||
</object>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
%>
|
|
||||||
<br/>
|
|
||||||
<span class='wiki_page'>Goto source: [[<%= wiki_name %>]]</span>
|
|
||||||
</div>
|
|
||||||
<%
|
|
||||||
content_for :header_tags do
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
if not @stylesheets_included
|
|
||||||
@stylesheets_included = true
|
|
||||||
%>
|
|
||||||
<%= stylesheet_link_tag "wiki_external_filter.css", :plugin => "wiki_external_filter", :media => :all %>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
if @flowplayer_used
|
|
||||||
if not @flowplayer_scripts_included
|
|
||||||
@flowplayer_scripts_included = true
|
|
||||||
%>
|
|
||||||
<%= javascript_include_tag 'flowplayer.min.js', :plugin => 'wiki_external_filter' %>
|
|
||||||
<script language="JavaScript">
|
|
||||||
//<![CDATA[
|
|
||||||
window.onload = function () {
|
|
||||||
flowplayer("a.flowplayer-video", "<%= ActionController::Base.relative_url_root + Engines::RailsExtensions::AssetHelpers.plugin_asset_path('wiki_external_filter', 'javascripts', 'flowplayer.swf') %>", { clip: { bufferLength: 1 } });
|
|
||||||
};
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
%>
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<%
|
||||||
|
require 'RMagick'
|
||||||
|
image = Magick::Image::from_blob(content[0]).first
|
||||||
|
%>
|
||||||
|
<a class='flowplayer-video<%= render_type == 'inline' ? " externalfilterinline" : "" %>' href='<%= ActionController::Base.relative_url_root + "/wiki_external_filter/#{macro}.flv?name=#{name}" %>' title='<%= h source %>' style='display:block;width:<%= image.columns %>px;height:<%= image.rows + 24 %>px;background-image:url(<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>);background-repeat:no-repeat'><%= image_tag 'play_large.png', :plugin => 'wiki_external_filter', :style => "display:block;position:relative;left:#{image.columns / 2 - 83 / 2}px;top:#{image.rows / 2 - 83 / 2}px" %></a>
|
||||||
|
<%
|
||||||
|
content_for :header_tags do
|
||||||
|
if not @flowplayer_scripts_included
|
||||||
|
@flowplayer_scripts_included = true
|
||||||
|
%>
|
||||||
|
<%= javascript_include_tag 'flowplayer.min.js', :plugin => 'wiki_external_filter' %>
|
||||||
|
<script language="JavaScript" type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
window.onload = function () {
|
||||||
|
flowplayer("a.flowplayer-video", "<%= ActionController::Base.relative_url_root + Engines::RailsExtensions::AssetHelpers.plugin_asset_path('wiki_external_filter', 'javascripts', 'flowplayer.swf') %>", { clip: { bufferLength: 1 } });
|
||||||
|
};
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
<%
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%>
|
|
@ -0,0 +1 @@
|
||||||
|
<img <%= render_type == 'inline' ? "class='externalfilterinline'" : "" %> src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' alt="<%= h source %>" />
|
|
@ -1,61 +0,0 @@
|
||||||
<%
|
|
||||||
case content_type
|
|
||||||
when /image\// then
|
|
||||||
%>
|
|
||||||
<img class='externalfilterinline' src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' alt="<%= h source %>" />
|
|
||||||
<%
|
|
||||||
when /text\/plain/ then
|
|
||||||
%>
|
|
||||||
<pre class='externalfilterinline'><%= h content[0] %></pre>
|
|
||||||
<%
|
|
||||||
when /\/.*(x|ht)ml/ then
|
|
||||||
%>
|
|
||||||
<div class='externalfilterinline'><%= content[0] %></div>
|
|
||||||
<%
|
|
||||||
when /video\/x\-flv/ then
|
|
||||||
require 'RMagick'
|
|
||||||
image = Magick::Image::from_blob(content[0]).first
|
|
||||||
%>
|
|
||||||
<a class='flowplayer-video externalfilterinline' href='<%= ActionController::Base.relative_url_root + "/wiki_external_filter/video.flv?name=#{name}" %>' alt='<%= h source %>' style='display:block;width:<%= image.columns %>px;height:<%= image.rows + 24 %>px;background-image:url(<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>);background-repeat:no-repeat'><%= image_tag 'play_large.png', :plugin => 'wiki_external_filter', :style => "display:block;position:relative;left:#{image.columns / 2 - 83 / 2}px;top:#{image.rows / 2 - 83 / 2}px" %></a>
|
|
||||||
|
|
||||||
<%
|
|
||||||
@flowplayer_used = true
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
else
|
|
||||||
%>
|
|
||||||
<object class='externalfilterinline' name='<%= name %>' data='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' type='<%= content_type %>' title="<%= h source %>">
|
|
||||||
<embed name='<%= name %>-2' src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' type='<%= content_type %>' title="<%= h source %>" />
|
|
||||||
</object>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
content_for :header_tags do
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
if not @stylesheets_included
|
|
||||||
@stylesheets_included = true
|
|
||||||
%>
|
|
||||||
<%= stylesheet_link_tag "wiki_external_filter.css", :plugin => "wiki_external_filter", :media => :all %>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
%>
|
|
||||||
<%
|
|
||||||
if @flowplayer_used
|
|
||||||
if not @flowplayer_scripts_included
|
|
||||||
@flowplayer_scripts_included = true
|
|
||||||
%>
|
|
||||||
<%= javascript_include_tag 'flowplayer.min.js', :plugin => 'wiki_external_filter' %>
|
|
||||||
<script language="JavaScript">
|
|
||||||
//<![CDATA[
|
|
||||||
window.onload = function () {
|
|
||||||
flowplayer("a.flowplayer-video", "<%= ActionController::Base.relative_url_root + Engines::RailsExtensions::AssetHelpers.plugin_asset_path('wiki_external_filter', 'javascripts', 'flowplayer.swf') %>", { clip: { bufferLength: 1 } });
|
|
||||||
};
|
|
||||||
//]]>
|
|
||||||
</script>
|
|
||||||
<%
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
%>
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
<img class='svg <%= render_type == 'inline' ? "externalfilterinline" : "" %>' src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' alt='<%= h source %>' />
|
||||||
|
<object class='svgobject <%= render_type == 'inline' ? "externalfilterinline" : "" %>' name='<%= name %>' data='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 0) %>' type='<%= content_types[0] %>' title="<%= h source %>">
|
||||||
|
<%
|
||||||
|
if content.size > 1
|
||||||
|
%>
|
||||||
|
<img<%= render_type == 'inline' ? " class='externalfilterinline'" : "" %> src='<%= url_for(:controller => 'wiki_external_filter', :action => 'filter', :macro => macro, :name => name, :index => 1) %>' alt='<%= h source %>' />
|
||||||
|
<%
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
</object>
|
||||||
|
<%
|
||||||
|
content_for :header_tags do
|
||||||
|
if not @svg_scripts_included
|
||||||
|
@svg_scripts_included = true
|
||||||
|
%>
|
||||||
|
<%= javascript_include_tag 'css_browser_selector.js', :plugin => 'wiki_external_filter' %>
|
||||||
|
<style type="text/css">
|
||||||
|
.svgobject { display: none }
|
||||||
|
.ie .svgobject { display: inline }
|
||||||
|
.ie img.svg { display: none }
|
||||||
|
.gecko .svgobject { display: inline }
|
||||||
|
.gecko img.svg { display: none }
|
||||||
|
</style>
|
||||||
|
<%
|
||||||
|
end
|
||||||
|
end
|
||||||
|
%>
|
|
@ -0,0 +1 @@
|
||||||
|
<span<%= render_type == 'inline' ? " class='externalfilterinline'" : "" %>><%= h content[0] %></span>
|
|
@ -0,0 +1,8 @@
|
||||||
|
/*
|
||||||
|
CSS Browser Selector v0.3.5 (Feb 05, 2010)
|
||||||
|
Rafael Lima (http://rafael.adm.br)
|
||||||
|
http://rafael.adm.br/css_browser_selector
|
||||||
|
License: http://creativecommons.org/licenses/by/2.5/
|
||||||
|
Contributors: http://rafael.adm.br/css_browser_selector#contributors
|
||||||
|
*/
|
||||||
|
function css_browser_selector(u){var ua = u.toLowerCase(),is=function(t){return ua.indexOf(t)>-1;},g='gecko',w='webkit',s='safari',o='opera',h=document.documentElement,b=[(!(/opera|webtv/i.test(ua))&&/msie\s(\d)/.test(ua))?('ie ie'+RegExp.$1):is('firefox/2')?g+' ff2':is('firefox/3.5')?g+' ff3 ff3_5':is('firefox/3')?g+' ff3':is('gecko/')?g:is('opera')?o+(/version\/(\d+)/.test(ua)?' '+o+RegExp.$1:(/opera(\s|\/)(\d+)/.test(ua)?' '+o+RegExp.$2:'')):is('konqueror')?'konqueror':is('chrome')?w+' chrome':is('iron')?w+' iron':is('applewebkit/')?w+' '+s+(/version\/(\d+)/.test(ua)?' '+s+RegExp.$1:''):is('mozilla/')?g:'',is('j2me')?'mobile':is('iphone')?'iphone':is('ipod')?'ipod':is('mac')?'mac':is('darwin')?'mac':is('webtv')?'webtv':is('win')?'win':is('freebsd')?'freebsd':(is('x11')||is('linux'))?'linux':'','js']; c = b.join(' '); h.className += ' '+c; return c;}; css_browser_selector(navigator.userAgent);
|
|
@ -1,3 +1,4 @@
|
||||||
ActionController::Routing::Routes.draw do |map|
|
ActionController::Routing::Routes.draw do |map|
|
||||||
map.connect 'wiki_external_filter/:filename', :controller => 'wiki_external_filter', :action => 'filter', :macro => 'flowplayer', :index => '1', :requirements => { :filename => /\S+\.flv/ }
|
map.connect 'wiki_external_filter/:filename', :controller => 'wiki_external_filter', :action => 'filter', :macro => 'video', :index => '1', :requirements => { :filename => /video\.flv/ }
|
||||||
|
map.connect 'wiki_external_filter/:filename', :controller => 'wiki_external_filter', :action => 'filter', :macro => 'video_url', :index => '1', :requirements => { :filename => /video_url\.flv/ }
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,28 +1,54 @@
|
||||||
development: &development
|
development: &development
|
||||||
plantuml:
|
plantuml:
|
||||||
description: "Constructs UML diagram image from its textual description in PlantUML language, see http://plantuml.sourceforge.net"
|
description: "Constructs UML diagram image from its textual description in PlantUML language, see http://plantuml.sourceforge.net"
|
||||||
command: "/usr/bin/plantuml -pipe"
|
template: image
|
||||||
content_type: "image/png"
|
outputs:
|
||||||
prolog: "@startuml"
|
- command: "/usr/bin/plantuml -pipe"
|
||||||
epilog: "@enduml"
|
content_type: "image/png"
|
||||||
|
prolog: "@startuml"
|
||||||
|
epilog: "@enduml"
|
||||||
graphviz:
|
graphviz:
|
||||||
description: "Constructs graph image from its textual description in DOT language, see http://www.graphviz.org"
|
description: "Constructs graph image from its textual description in DOT language, see http://www.graphviz.org"
|
||||||
command: "/usr/bin/dot -Tsvg"
|
template: svg
|
||||||
content_type: "image/svg+xml"
|
outputs:
|
||||||
|
- command: "/usr/bin/dot -Tsvg"
|
||||||
|
content_type: "image/svg+xml"
|
||||||
|
- command: "/usr/bin/dot -Tpng"
|
||||||
|
content_type: "image/png"
|
||||||
ritex:
|
ritex:
|
||||||
description: "Converts WebTeX expression to MathML, see http://ritex.rubyforge.org/"
|
description: "Converts WebTeX expression to MathML, see http://ritex.rubyforge.org/"
|
||||||
command: "(echo '<!DOCTYPE math PUBLIC \"-//W3C//DTD MathML 2.0//EN\" \"http://www.w3.org/Math/DTD/mathml2/mathml2.dtd\">'; /usr/bin/ritex) | xmllint --noent --nonet --catalogs --loaddtd - | sed 's/^<!DOCTYPE.\\+$//' | /usr/bin/math2svg"
|
template: svg
|
||||||
content_type: "image/svg+xml"
|
outputs:
|
||||||
# For MathML-compliant browsers and when Redmine is fully XML-compliant.
|
- command: "(echo '<!DOCTYPE math PUBLIC \"-//W3C//DTD MathML 2.0//EN\" \"http://www.w3.org/Math/DTD/mathml2/mathml2.dtd\">'; /usr/bin/ritex) | xmllint --noent --nonet --catalogs --loaddtd - | sed 's/^<!DOCTYPE.\\+$//' | /usr/bin/math2svg"
|
||||||
# ritex:
|
content_type: "image/svg+xml"
|
||||||
# description: "Converts WebTeX expression to MathML, see http://ritex.rubyforge.org/"
|
video:
|
||||||
# command: "/usr/bin/ritex"
|
description: "Converts video file given by its filename to FLV and displays it via Flowplayer"
|
||||||
# content_type: "application/xhtml+xml"
|
template: flash-video
|
||||||
|
replace_attachments: true
|
||||||
|
outputs:
|
||||||
|
- command: "xargs -I{} ffmpeg -i {} -vframes 1 -f mjpeg -"
|
||||||
|
content_type: "image/jpeg"
|
||||||
|
# We have to use temporary file as otherwise ffmpeg is unable to inject
|
||||||
|
# metadata.
|
||||||
|
- command: "FN=`cat`; if [ `echo ${FN##*.} | tr [:upper:] [:lower:]` != 'flv' ]; then TMPVIDEO=`tempfile --directory=/var/tmp`; ffmpeg -y -i $FN -sameq -ar 44100 -f flv $TMPVIDEO; STATUS=$?; cat $TMPVIDEO; rm $TMPVIDEO; exit $STATUS; else cat $FN; fi"
|
||||||
|
content_type: "video/x-flv"
|
||||||
|
video_url:
|
||||||
|
description: "Converts video file given by its URL to FLV and displays it via Flowplayer"
|
||||||
|
template: flash-video
|
||||||
|
outputs:
|
||||||
|
- command: "wget -i - -O - | ffmpeg -i - -vframes 1 -f mjpeg -"
|
||||||
|
content_type: "image/jpeg"
|
||||||
|
# We have to use temporary file as otherwise ffmpeg is unable to inject
|
||||||
|
# metadata.
|
||||||
|
- command: "FN=`cat`; wget $FN -O - | (if [ `echo ${FN##*.} | tr [:upper:] [:lower:]` != 'flv' ]; then TMPVIDEO=`tempfile --directory=/var/tmp`; ffmpeg -y -i - -sameq -ar 44100 -f flv $TMPVIDEO; STATUS=$?; cat $TMPVIDEO; rm $TMPVIDEO; exit $STATUS; else cat; fi)"
|
||||||
|
content_type: "video/x-flv"
|
||||||
fortune:
|
fortune:
|
||||||
description: "Prints a random, hopefully interesting, adage, see http://en.wikipedia.org/wiki/Fortune_(Unix)"
|
description: "Prints a random, hopefully interesting, adage, see http://en.wikipedia.org/wiki/Fortune_(Unix)"
|
||||||
command: "/usr/bin/fortune"
|
template: text
|
||||||
cache_seconds: 0
|
cache_seconds: 0
|
||||||
content_type: "text/plain"
|
outputs:
|
||||||
|
- command: "/usr/bin/fortune"
|
||||||
|
content_type: "text/plain"
|
||||||
|
|
||||||
test:
|
test:
|
||||||
type: mock
|
type: mock
|
||||||
|
|
2
init.rb
2
init.rb
|
@ -19,7 +19,7 @@ Redmine::Plugin.register :wiki_external_filter do
|
||||||
info = config[name]
|
info = config[name]
|
||||||
desc info['description']
|
desc info['description']
|
||||||
macro name do |obj, args|
|
macro name do |obj, args|
|
||||||
m = WikiExternalFilterHelper::Macro.new(self, args.to_s, obj.page.attachments, name, info)
|
m = WikiExternalFilterHelper::Macro.new(self, args.to_s, obj ? obj.page.attachments : nil, name, info)
|
||||||
m.render
|
m.render
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Reference in New Issue