Improved rendering
[phpeclipse.git] / archive / org.plog4u.wiki / src / org / plog4u / wiki / macro / CodeMacro.java
1 /*
2  * This file is part of "SnipSnap Radeox Rendering Engine".
3  * 
4  * Copyright (c) 2002 Stephan J. Schmidt, Matthias L. Jugel All Rights Reserved.
5  * 
6  * Please visit http://radeox.org/ for updates and contact.
7  * 
8  * --LICENSE NOTICE-- This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser
9  * General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any
10  * later version.
11  * 
12  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14  * 
15  * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA --LICENSE NOTICE--
17  */
18
19 package org.plog4u.wiki.macro;
20
21 import java.io.IOException;
22 import java.io.Writer;
23 import java.util.HashMap;
24 import java.util.Iterator;
25 import java.util.Locale;
26 import java.util.Map;
27 import java.util.ResourceBundle;
28
29
30 //import org.apache.commons.logging.Log;
31 //import org.apache.commons.logging.LogFactory;
32 import org.plog4u.wiki.filter.ICachableMacro;
33 import org.plog4u.wiki.filter.INoParserBodyFilterMacro;
34 import org.plog4u.wiki.macro.code.AbstractCPPBasedCodeFilter;
35 import org.radeox.api.engine.context.InitialRenderContext;
36 import org.radeox.api.engine.context.RenderContext;
37 import org.radeox.filter.context.BaseFilterContext;
38 import org.radeox.filter.context.FilterContext;
39 import org.radeox.macro.LocalePreserved;
40 import org.radeox.macro.code.SourceCodeFormatter;
41 import org.radeox.macro.parameter.MacroParameter;
42 import org.radeox.util.Encoder;
43 import org.radeox.util.Service;
44  
45 /*
46  * Macro for displaying programming language source code. CodeMacro knows about different source code formatters which can be
47  * plugged into radeox to display more languages. CodeMacro displays Java, Ruby or SQL code.
48  * 
49  * @author stephan @team sonicteam
50  * 
51  */
52
53 public class CodeMacro extends LocalePreserved implements INoParserBodyFilterMacro, ICachableMacro {
54 //  private static Log log = LogFactory.getLog(CodeMacro.class);
55
56   private Map formatters;
57   private FilterContext nullContext = new BaseFilterContext();
58
59   private String start;
60   private String end;
61
62   private String[] paramDescription = { "?1: syntax highlighter to use, defaults to java" };
63
64   public String[] getParamDescription() {
65     return paramDescription;
66   }
67
68   public String getLocaleKey() {
69     return "macro.code";
70   }
71
72   public void setInitialContext(InitialRenderContext context) {
73     super.setInitialContext(context);
74     Locale outputLocale = (Locale) context.get(RenderContext.OUTPUT_LOCALE);
75     String outputName = (String) context.get(RenderContext.OUTPUT_BUNDLE_NAME);
76     ResourceBundle outputMessages = ResourceBundle.getBundle(outputName, outputLocale);
77
78     start = outputMessages.getString(getLocaleKey() + ".start");
79     end = outputMessages.getString(getLocaleKey() + ".end");
80   }
81
82   public CodeMacro() {
83     formatters = new HashMap();
84
85     Iterator formatterIt = Service.providers(SourceCodeFormatter.class);
86     while (formatterIt.hasNext()) {
87       try {
88         SourceCodeFormatter formatter = (SourceCodeFormatter) formatterIt.next();
89         String name = formatter.getName();
90         if (formatters.containsKey(name)) {
91           SourceCodeFormatter existing = (SourceCodeFormatter) formatters.get(name);
92           if (existing.getPriority() < formatter.getPriority()) {
93             formatters.put(name, formatter);
94 //            log.debug("Replacing formatter: " + formatter.getClass() + " (" + name + ")");
95           }
96         } else {
97           formatters.put(name, formatter);
98 //          log.debug("Loaded formatter: " + formatter.getClass() + " (" + name + ")");
99         }
100       } catch (Exception e) {
101 //        log.warn("CodeMacro: unable to load code formatter", e);
102       }
103     }
104
105     addSpecial('[');
106     addSpecial(']');
107     addSpecial('{');
108     addSpecial('}');
109     addSpecial('*');
110     addSpecial('-');
111     addSpecial('\\');
112   }
113
114   public void execute(Writer writer, MacroParameter params) throws IllegalArgumentException, IOException {
115
116     SourceCodeFormatter formatter = null;
117     String result;
118     if (params.getLength() == 0 || !formatters.containsKey(params.get("0"))) {
119       formatter = (SourceCodeFormatter) formatters.get(initialContext.get(RenderContext.DEFAULT_FORMATTER));
120       if (null == formatter) {
121         System.err.println("Formatter not found.");
122         formatter = (SourceCodeFormatter) formatters.get("java");
123         result = formatter.filter(params.getContent(), nullContext);
124       } else if (formatter instanceof AbstractCPPBasedCodeFilter) {
125         result = formatter.filter(params.getContent(), nullContext);
126       } else {
127         result = formatter.filter(Encoder.escape(params.getContent()), nullContext);
128       }
129     } else {
130       formatter = (SourceCodeFormatter) formatters.get(params.get("0"));
131       if (formatter instanceof AbstractCPPBasedCodeFilter) {
132         result = formatter.filter(params.getContent(), nullContext);
133       } else {
134         result = formatter.filter(Encoder.escape(params.getContent()), nullContext);
135       }
136     }
137
138     writer.write(start);
139     writer.write(replace(result.trim()));
140     writer.write(end);
141     return;
142   }
143 }