Source code: com/xpn/xwiki/render/filter/XWikiHeadingFilter.java
1 package com.xpn.xwiki.render.filter;
2
3 import java.text.MessageFormat;
4 import java.util.ArrayList;
5 import java.util.Iterator;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.radeox.api.engine.context.InitialRenderContext;
10 import org.radeox.api.engine.context.RenderContext;
11 import org.radeox.filter.CacheFilter;
12 import org.radeox.filter.context.FilterContext;
13 import org.radeox.filter.regex.LocaleRegexTokenFilter;
14 import org.radeox.regex.MatchResult;
15
16 import com.xpn.xwiki.render.XWikiRadeoxRenderEngine;
17 import com.xpn.xwiki.util.TOCGenerator;
18 import com.xpn.xwiki.XWikiContext;
19
20
21 /**
22 * A customized version of Radeox Heading Filter
23 */
24 public class XWikiHeadingFilter extends LocaleRegexTokenFilter implements CacheFilter {
25 private final String TOC_NUMBERED = "tocNumbered";
26 private final String TOC_DATA = "tocData";
27
28 private MessageFormat formatter;
29
30
31 protected String getLocaleKey() {
32 return "filter.heading";
33 }
34
35 public void handleMatch(StringBuffer buffer, MatchResult result, FilterContext context) {
36 buffer.append(handleMatch(result, context));
37 }
38
39 public void setInitialContext(InitialRenderContext context) {
40 super.setInitialContext(context);
41 String outputTemplate = outputMessages.getString(getLocaleKey()+".print");
42 formatter = new MessageFormat("");
43 formatter.applyPattern(outputTemplate);
44 }
45
46 public String handleMatch(MatchResult result, FilterContext context) {
47 String id = null;
48 String level = result.group(1);
49 String text = result.group(3);
50 String numbering = "";
51
52 RenderContext rcontext = context.getRenderContext();
53 XWikiContext xcontext = ((XWikiRadeoxRenderEngine) rcontext.getRenderEngine()).getContext();
54
55 // generate unique ID of the heading
56 List processedHeadings = (List) rcontext.get("processedHeadings");
57 if (processedHeadings == null) {
58 processedHeadings = new ArrayList();
59 rcontext.set("processedHeadings", processedHeadings);
60 }
61 int occurence = 0;
62 for (Iterator iter = processedHeadings.iterator(); iter.hasNext();) if (iter.next().equals(text)) occurence++;
63 id = TOCGenerator.makeHeadingID(text, occurence);
64 processedHeadings.add(text);
65
66 // add numbering if the flag is set
67 if (xcontext.containsKey(TOC_NUMBERED) && ((Boolean)xcontext.get(TOC_NUMBERED)).booleanValue()) {
68 if (xcontext.containsKey(TOC_DATA)) {
69 Map tocEntry = (Map) ((Map) xcontext.get(TOC_DATA)).get(id);
70 if (tocEntry != null) numbering = (String) tocEntry.get(TOCGenerator.TOC_DATA_NUMBERING) + " ";
71 }
72 }
73
74 return formatter.format(new Object[]{id, level.replace('.', '-'), numbering, text});
75 }
76 }