Clover Coverage Report - XWiki Rendering - Parent POM 4.0-SNAPSHOT (Aggregated)
Coverage timestamp: Mon Mar 12 2012 18:03:13 CET
../../../../../../img/srcFileCovDistChart9.png 55% of files have more coverage
86   269   43   5.38
42   183   0.5   16
16     2.69  
1    
 
  XWikiSyntaxEscapeWikiPrinter       Line # 37 86 0% 43 16 88.9% 0.8888889
 
  (326)
 
1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.rendering.internal.renderer.xwiki20;
21   
22    import java.util.Stack;
23    import java.util.regex.Matcher;
24    import java.util.regex.Pattern;
25   
26    import org.xwiki.rendering.renderer.printer.LookaheadWikiPrinter;
27    import org.xwiki.rendering.renderer.printer.WikiPrinter;
28   
29    /**
30    * A Wiki printer that knows how to escape characters that would otherwise mean something different in XWiki wiki
31    * syntax. For example if we have "**" as special symbols (and not as a Bold Format block) we need to escape them to
32    * "~*~*" as otherwise they'd be considered bold after being rendered.
33    *
34    * @version $Id: 9c9ab16d66d93c20b0f003b9b6aa4333e705d9a7 $
35    * @since 1.7
36    */
 
37    public class XWikiSyntaxEscapeWikiPrinter extends LookaheadWikiPrinter
38    {
39    private static final Pattern VERBATIM_PATTERN = Pattern.compile("(\\{\\{\\{)|(\\}\\}\\})");
40   
41    private XWikiSyntaxListenerChain listenerChain;
42   
43    private XWikiSyntaxEscapeHandler escapeHandler;
44   
45    private boolean escapeLastChar;
46   
47    private Pattern escapeFirstIfMatching;
48   
49    private String lastPrinted;
50   
 
51  447 toggle public XWikiSyntaxEscapeWikiPrinter(WikiPrinter printer, XWikiSyntaxListenerChain listenerChain)
52    {
53  447 super(printer);
54   
55  447 this.escapeHandler = new XWikiSyntaxEscapeHandler();
56   
57  447 this.listenerChain = listenerChain;
58    }
59   
 
60  0 toggle public XWikiSyntaxEscapeHandler getEscapeHandler()
61    {
62  0 return escapeHandler;
63    }
64   
 
65  2407 toggle @Override
66    protected void printInternal(String text)
67    {
68  2407 super.printInternal(text);
69   
70  2407 int length = text.length();
71   
72  2407 if (length > 0) {
73  2380 this.escapeHandler.setOnNewLine(text.charAt(length - 1) == '\n');
74    }
75   
76  2407 this.lastPrinted = text;
77    }
78   
 
79  0 toggle @Override
80    protected void printlnInternal(String text)
81    {
82  0 super.printlnInternal(text);
83   
84  0 this.escapeHandler.setOnNewLine(true);
85   
86  0 this.lastPrinted = "\n";
87    }
88   
 
89  3012 toggle @Override
90    public void flush()
91    {
92  3012 if (getBuffer().length() > 0) {
93  640 this.escapeHandler.escape(getBuffer(), this.listenerChain, this.escapeLastChar, this.escapeFirstIfMatching);
94  640 super.flush();
95    }
96  3012 this.escapeLastChar = false;
97  3012 this.escapeFirstIfMatching = null;
98    }
99   
 
100  25 toggle public void printBeginBold()
101    {
102  25 flush();
103   
104  25 boolean isOnNewLine = this.escapeHandler.isOnNewLine();
105   
106  25 print("**");
107   
108  25 if (isOnNewLine) {
109  6 this.escapeFirstIfMatching = XWikiSyntaxEscapeHandler.STARLISTEND_PATTERN;
110    }
111    }
112   
 
113  1 toggle public void setEscapeLastChar(boolean escapeLastChar)
114    {
115  1 this.escapeLastChar = escapeLastChar;
116    }
117   
 
118  156 toggle public void setBeforeLink(boolean beforeLink)
119    {
120  156 this.escapeHandler.setBeforeLink(beforeLink);
121    }
122   
 
123  77 toggle public void setOnNewLine(boolean onNewLine)
124    {
125  77 this.escapeHandler.setOnNewLine(onNewLine);
126    }
127   
 
128  84 toggle public boolean isOnNewLine()
129    {
130  84 return this.escapeHandler.isOnNewLine();
131    }
132   
 
133  7 toggle public boolean isAfterWhiteSpace()
134    {
135  7 return isOnNewLine() || Character.isWhitespace(getLastPrinted().charAt(getLastPrinted().length() - 1));
136    }
137   
 
138  22 toggle public String getLastPrinted()
139    {
140  22 return this.lastPrinted;
141    }
142   
 
143  19 toggle public void printBeginItalic()
144    {
145    // If the lookahead buffer is not empty and the last character is ":" then we need to escape it
146    // since otherwise we would get "://" which could be confused for a URL.
147  19 if (getBuffer().length() > 0 && getBuffer().charAt(getBuffer().length() - 1) == ':') {
148  1 this.escapeLastChar = true;
149    }
150   
151  19 print("//");
152    }
153   
 
154  19 toggle public void printEndItalic()
155    {
156    // If the lookahead buffer is not empty and the last character is ":" then we need to escape it
157    // since otherwise we would get "://" which could be confused for a URL.
158  19 if (getBuffer().length() > 0 && getBuffer().charAt(getBuffer().length() - 1) == ':') {
159  1 this.escapeLastChar = true;
160    }
161   
162  19 print("//");
163    }
164   
 
165  25 toggle public void printInlineMacro(String xwikiSyntaxText)
166    {
167    // If the lookahead buffer is not empty and the last character is "{" then we need to escape it
168    // since otherwise we would get "{{{" which could be confused for a verbatim block.
169  25 if (getBuffer().length() > 0 && getBuffer().charAt(getBuffer().length() - 1) == '{') {
170  1 this.escapeLastChar = true;
171    }
172   
173  25 print(xwikiSyntaxText);
174    }
175   
 
176  20 toggle public void printVerbatimContent(String verbatimContent)
177    {
178  20 StringBuffer result = new StringBuffer();
179   
180  20 Stack<StringBuffer> subVerbatimStack = new Stack<StringBuffer>();
181  20 boolean printEndVerbatim = false;
182   
183  20 Matcher matcher = VERBATIM_PATTERN.matcher(verbatimContent);
184  20 int currentIndex = 0;
185  28 for (; matcher.find(); currentIndex = matcher.end()) {
186  8 String before = verbatimContent.substring(currentIndex, matcher.start());
187   
188  8 if (printEndVerbatim) {
189  1 if (before.startsWith("}")) {
190  0 result.append("~}~}~}");
191    } else {
192  1 result.append("~}}}");
193    }
194    }
195   
196  8 if (subVerbatimStack.size() == 0) {
197  6 result.append(before);
198    } else {
199  2 subVerbatimStack.peek().append(before);
200    }
201   
202  8 if (matcher.group(1) != null) {
203  4 subVerbatimStack.push(new StringBuffer());
204    } else {
205  4 if (subVerbatimStack.size() == 0) {
206  3 printEndVerbatim = true;
207    } else {
208  1 StringBuffer subVerbatim = subVerbatimStack.pop();
209   
210  1 if (subVerbatimStack.size() == 0) {
211  1 result.append("{{{");
212  1 result.append(subVerbatim);
213  1 result.append("}}}");
214    } else {
215  0 subVerbatimStack.peek().append("{{{");
216  0 subVerbatimStack.peek().append(subVerbatim);
217  0 subVerbatimStack.peek().append("}}}");
218    }
219    }
220    }
221    }
222   
223  20 if (currentIndex == 0) {
224  15 print(verbatimContent);
225  15 return;
226    }
227   
228  5 String end = verbatimContent.substring(currentIndex);
229   
230  5 if (printEndVerbatim) {
231  2 if (end.length() == 0 || end.charAt(0) == '}') {
232  1 result.append("~}~}~}");
233    } else {
234  1 result.append("~}}}");
235    }
236    }
237   
238  5 if (subVerbatimStack.size() > 0) {
239    // Append remaining string
240  2 subVerbatimStack.peek().append(end);
241   
242    // Escape not closed verbatim blocks
243  5 while (subVerbatimStack.size() > 0) {
244  3 StringBuffer subVerbatim = subVerbatimStack.pop();
245   
246  3 if (subVerbatimStack.size() == 0) {
247  2 if (subVerbatim.length() > 0 && subVerbatim.charAt(0) == '{') {
248  0 result.append("~{~{~{");
249    } else {
250  2 result.append("~{{{");
251    }
252  2 result.append(subVerbatim);
253    } else {
254  1 if (subVerbatim.length() > 0 && subVerbatim.charAt(0) == '{') {
255  1 subVerbatimStack.peek().append("~{~{~{");
256    } else {
257  0 subVerbatimStack.peek().append("~{{{");
258    }
259  1 subVerbatimStack.peek().append(subVerbatim);
260    }
261    }
262    } else {
263    // Append remaining string
264  3 result.append(end);
265    }
266   
267  5 print(result.toString());
268    }
269    }