1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.renderer.xwiki20

File XWikiSyntaxChainingRenderer.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

84
248
59
1
786
556
121
0.49
4.2
59
2.05

Classes

Class Line # Actions
XWikiSyntaxChainingRenderer 46 248 0% 121 3
0.992327499.2%
 

Contributing tests

This file is covered by 278 tests. .

Source view

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.Map;
23   
24    import org.apache.commons.lang3.StringUtils;
25    import org.xwiki.rendering.internal.renderer.xwiki20.reference.XWikiSyntaxResourceRenderer;
26    import org.xwiki.rendering.listener.Format;
27    import org.xwiki.rendering.listener.HeaderLevel;
28    import org.xwiki.rendering.listener.ListType;
29    import org.xwiki.rendering.listener.MetaData;
30    import org.xwiki.rendering.listener.chaining.BlockStateChainingListener;
31    import org.xwiki.rendering.listener.chaining.ListenerChain;
32    import org.xwiki.rendering.listener.chaining.StackableChainingListener;
33    import org.xwiki.rendering.listener.reference.ResourceReference;
34    import org.xwiki.rendering.renderer.AbstractChainingPrintRenderer;
35    import org.xwiki.rendering.renderer.printer.DefaultWikiPrinter;
36    import org.xwiki.rendering.renderer.printer.VoidWikiPrinter;
37    import org.xwiki.rendering.renderer.printer.WikiPrinter;
38    import org.xwiki.rendering.renderer.reference.ResourceReferenceSerializer;
39   
40    /**
41    * Convert listener events to XWiki Syntax 2.0 output.
42    *
43    * @version $Id: f6d0547e4997334291caea5926bb2a37c7d99ac9 $
44    * @since 1.8RC1
45    */
 
46    public class XWikiSyntaxChainingRenderer extends AbstractChainingPrintRenderer implements StackableChainingListener
47    {
48    private XWikiSyntaxResourceRenderer linkResourceRenderer;
49   
50    private XWikiSyntaxResourceRenderer imageResourceRenderer;
51   
52    private XWikiSyntaxMacroRenderer macroPrinter;
53   
54    protected ResourceReferenceSerializer linkReferenceSerializer;
55   
56    protected ResourceReferenceSerializer imageReferenceSerializer;
57   
58    // Custom States
59   
60    private boolean isFirstElementRendered = false;
61   
62    private StringBuffer listStyle = new StringBuffer();
63   
64    private Map<String, String> previousFormatParameters;
65   
66    /**
67    * @since 2.5RC1
68    */
 
69  363 toggle public XWikiSyntaxChainingRenderer(ListenerChain listenerChain,
70    ResourceReferenceSerializer linkReferenceSerializer, ResourceReferenceSerializer imageReferenceSerializer)
71    {
72  363 setListenerChain(listenerChain);
73   
74  363 this.linkReferenceSerializer = linkReferenceSerializer;
75  363 this.imageReferenceSerializer = imageReferenceSerializer;
76  363 this.linkResourceRenderer = createXWikiSyntaxLinkRenderer(getListenerChain(), linkReferenceSerializer);
77  363 this.imageResourceRenderer = createXWikiSyntaxImageRenderer(getListenerChain(), imageReferenceSerializer);
78  363 this.macroPrinter = new XWikiSyntaxMacroRenderer();
79    }
80   
81    /**
82    * @since 2.5RC1
83    */
 
84  259 toggle protected XWikiSyntaxResourceRenderer createXWikiSyntaxLinkRenderer(ListenerChain listenerChain,
85    ResourceReferenceSerializer linkReferenceSerializer)
86    {
87  259 return new XWikiSyntaxResourceRenderer((XWikiSyntaxListenerChain) listenerChain, linkReferenceSerializer);
88    }
89   
90    /**
91    * @since 2.5RC1
92    */
 
93  259 toggle protected XWikiSyntaxResourceRenderer createXWikiSyntaxImageRenderer(ListenerChain listenerChain,
94    ResourceReferenceSerializer imageReferenceSerializer)
95    {
96  259 return new XWikiSyntaxResourceRenderer((XWikiSyntaxListenerChain) listenerChain, imageReferenceSerializer);
97    }
98   
99    // State
100   
 
101  665 toggle private BlockStateChainingListener getBlockState()
102    {
103  665 return getXWikiSyntaxListenerChain().getBlockStateChainingListener();
104    }
105   
 
106  28 toggle @Override
107    public StackableChainingListener createChainingListenerInstance()
108    {
109  28 XWikiSyntaxChainingRenderer renderer = new XWikiSyntaxChainingRenderer(getListenerChain(),
110    this.linkReferenceSerializer, this.imageReferenceSerializer);
111  28 renderer.setPrinter(getPrinter());
112  28 return renderer;
113    }
114   
 
115  974 toggle private XWikiSyntaxListenerChain getXWikiSyntaxListenerChain()
116    {
117  974 return (XWikiSyntaxListenerChain) getListenerChain();
118    }
119   
 
120  366 toggle private XWikiSyntaxResourceRenderer getLinkRenderer()
121    {
122  366 return this.linkResourceRenderer;
123    }
124   
 
125  74 toggle private XWikiSyntaxResourceRenderer getImageRenderer()
126    {
127  74 return this.imageResourceRenderer;
128    }
129   
 
130  47 toggle private XWikiSyntaxMacroRenderer getMacroPrinter()
131    {
132  47 return this.macroPrinter;
133    }
134   
 
135  29 toggle @Override
136    public void beginGroup(Map<String, String> parameters)
137    {
138  29 if (!getBlockState().isInLine()) {
139  20 printEmptyLine();
140    }
141   
142  29 if (parameters.size() > 0) {
143  11 printParameters(parameters, true);
144    }
145   
146  29 print("(((");
147  29 print("\n");
148   
149    // Create a new listener stack in order to preserve current states, to handle the group.
150  29 getListenerChain().pushAllStackableListeners();
151    }
152   
153    /**
154    * {@inheritDoc}
155    *
156    * @since 3.0M2
157    */
 
158  511 toggle @Override
159    public void endDocument(MetaData metadata)
160    {
161    // Ensure that all data in the escape printer have been flushed
162  511 getXWikiPrinter().flush();
163    }
164   
 
165  29 toggle @Override
166    public void endGroup(Map<String, String> parameters)
167    {
168  29 print("\n");
169  29 print(")))");
170   
171    // Restore previous listeners that were stacked
172  29 getListenerChain().popAllStackableListeners();
173    }
174   
 
175  93 toggle @Override
176    public void beginLink(ResourceReference reference, boolean freestanding, Map<String, String> parameters)
177    {
178    // Flush test content before the link.
179    // TODO: improve the block state renderer to be able to make the difference between what is bufferized
180    // before the link and what in the label link
181  93 getXWikiPrinter().setBeforeLink(true);
182    // escape open link syntax when before a link
183  93 if (getLinkRenderer().forceFullSyntax(getXWikiPrinter(), freestanding, parameters)
184    && getXWikiPrinter().getBuffer().length() > 0
185    && getXWikiPrinter().getBuffer().charAt(getXWikiPrinter().getBuffer().length() - 1) == '[') {
186  1 getXWikiPrinter().setEscapeLastChar(true);
187    }
188  93 getXWikiPrinter().flush();
189  93 getXWikiPrinter().setBeforeLink(false);
190   
191  93 int linkDepth = getBlockState().getLinkDepth();
192   
193    // If we are at a depth of 2 or greater it means we're in a link inside a link and in this case we
194    // shouldn't output the nested link as a link unless it's a free standing link.
195  93 if (linkDepth < 2) {
196  92 getLinkRenderer().beginRenderLink(getXWikiPrinter(), reference, freestanding, parameters);
197   
198  92 XWikiSyntaxEscapeWikiPrinter linkLabelPrinter =
199    new XWikiSyntaxEscapeWikiPrinter(new DefaultWikiPrinter(), getXWikiSyntaxListenerChain());
200   
201    // Make sure the escape handler knows there is already characters before
202  92 linkLabelPrinter.setOnNewLine(getXWikiPrinter().isOnNewLine());
203   
204    // Defer printing the link content since we need to gather all nested elements
205  92 pushPrinter(linkLabelPrinter);
206  1 } else if (freestanding) {
207  1 print(getLinkRenderer().serialize(reference, freestanding));
208    }
209    }
210   
 
211  91 toggle @Override
212    public void endLink(ResourceReference reference, boolean freestanding, Map<String, String> parameters)
213    {
214    // The links in a top level link label are not rendered as link (only the label is printed)
215  91 if (getBlockState().getLinkDepth() == 1) {
216  90 XWikiSyntaxEscapeWikiPrinter linkBlocksPrinter = getXWikiPrinter();
217  90 linkBlocksPrinter.flush();
218  90 String content = linkBlocksPrinter.toString();
219  90 popPrinter();
220   
221  90 getLinkRenderer().renderLinkContent(getXWikiPrinter(), content);
222  90 getLinkRenderer().endRenderLink(getXWikiPrinter(), reference, freestanding, parameters);
223    }
224    }
225   
 
226  112 toggle @Override
227    public void beginFormat(Format format, Map<String, String> parameters)
228    {
229    // If the previous format had parameters and the parameters are different from the current ones then close them
230  112 if (this.previousFormatParameters != null) {
231  31 if (parameters.isEmpty()) {
232    // print("(%%)");
233    // this.previousFormatParameters = null;
234  29 } else if (!this.previousFormatParameters.equals(parameters)) {
235  28 this.previousFormatParameters = null;
236  28 printParameters(parameters, false);
237    } else {
238  1 this.previousFormatParameters = null;
239    }
240  81 } else if (this.previousFormatParameters == null) {
241  81 printParameters(parameters, false);
242    }
243   
244  112 switch (format) {
245  18 case BOLD:
246    // Handle empty formatting parameters.
247  18 if (this.previousFormatParameters != null) {
248  1 getPrinter().print("(%%)");
249  1 this.previousFormatParameters = null;
250    }
251   
252  18 getXWikiPrinter().printBeginBold();
253  18 break;
254  17 case ITALIC:
255    // Handle empty formatting parameters.
256  17 if (this.previousFormatParameters != null) {
257  1 getPrinter().print("(%%)");
258  1 this.previousFormatParameters = null;
259    }
260   
261  17 getXWikiPrinter().printBeginItalic();
262  17 break;
263  4 case STRIKEDOUT:
264  4 print("--");
265  4 break;
266  2 case UNDERLINED:
267  2 print("__");
268  2 break;
269  3 case SUPERSCRIPT:
270  3 print("^^");
271  3 break;
272  3 case SUBSCRIPT:
273  3 print(",,");
274  3 break;
275  4 case MONOSPACE:
276  4 print("##");
277  4 break;
278  61 case NONE:
279  61 break;
280    }
281    }
282   
 
283  112 toggle @Override
284    public void endFormat(Format format, Map<String, String> parameters)
285    {
286  112 switch (format) {
287  18 case BOLD:
288  18 print("**");
289  18 break;
290  17 case ITALIC:
291  17 getXWikiPrinter().printEndItalic();
292  17 break;
293  4 case STRIKEDOUT:
294  4 print("--");
295  4 break;
296  2 case UNDERLINED:
297  2 print("__");
298  2 break;
299  3 case SUPERSCRIPT:
300  3 print("^^");
301  3 break;
302  3 case SUBSCRIPT:
303  3 print(",,");
304  3 break;
305  4 case MONOSPACE:
306  4 print("##");
307  4 break;
308  61 case NONE:
309  61 break;
310    }
311  112 if (!parameters.isEmpty()) {
312  70 this.previousFormatParameters = parameters;
313    }
314    }
315   
 
316  284 toggle @Override
317    public void beginParagraph(Map<String, String> parameters)
318    {
319  284 printEmptyLine();
320  284 printParameters(parameters);
321    }
322   
 
323  282 toggle @Override
324    public void endParagraph(Map<String, String> parameters)
325    {
326  282 this.previousFormatParameters = null;
327   
328    // Ensure that any not printed characters are flushed.
329    // TODO: Fix this better by introducing a state listener to handle escapes
330  282 getXWikiPrinter().flush();
331    }
332   
 
333  101 toggle @Override
334    public void onNewLine()
335    {
336    // - If we're inside a table cell, a paragraph, a list or a section header then if we have already outputted
337    // a new line before then this new line should be a line break in order not to break the table cell,
338    // paragraph, list or section header.
339   
340    // - If the new line is the last element of the paragraph, list or section header then it should be a line break
341    // as otherwise it'll be considered as an empty line event next time the generated syntax is read by the XWiki
342    // parser.
343   
344  101 if (getBlockState().isInLine()) {
345  99 if (getXWikiSyntaxListenerChain().getConsecutiveNewLineStateChainingListener().getNewLineCount() > 1) {
346  6 print("\\\\");
347  93 } else if (getXWikiSyntaxListenerChain().getLookaheadChainingListener().getNextEvent().eventType
348    .isInlineEnd()) {
349  8 print("\\\\");
350    } else {
351  85 print("\n");
352    }
353    } else {
354  2 print("\n");
355    }
356    }
357   
 
358  22 toggle @Override
359    public void onMacro(String id, Map<String, String> parameters, String content, boolean inline)
360    {
361  22 if (!inline) {
362  14 printEmptyLine();
363  14 print(getMacroPrinter().renderMacro(id, parameters, content, inline));
364    } else {
365  8 getXWikiPrinter().printInlineMacro(getMacroPrinter().renderMacro(id, parameters, content, inline));
366    }
367    }
368   
 
369  60 toggle @Override
370    public void beginHeader(HeaderLevel level, String id, Map<String, String> parameters)
371    {
372  60 printEmptyLine();
373  60 printParameters(parameters);
374  60 print(StringUtils.repeat("=", level.getAsInt()) + " ");
375    }
376   
 
377  60 toggle @Override
378    public void endHeader(HeaderLevel level, String id, Map<String, String> parameters)
379    {
380  60 print(" " + StringUtils.repeat("=", level.getAsInt()));
381    }
382   
 
383  1067 toggle @Override
384    public void onWord(String word)
385    {
386  1067 printDelayed(word);
387    }
388   
 
389  603 toggle @Override
390    public void onSpace()
391    {
392  603 printDelayed(" ");
393    }
394   
 
395  276 toggle @Override
396    public void onSpecialSymbol(char symbol)
397    {
398  276 printDelayed("" + symbol);
399    }
400   
 
401  64 toggle @Override
402    public void beginList(ListType type, Map<String, String> parameters)
403    {
404    // This need to be done in case of a subitem before endListItem() is not called
405  64 this.previousFormatParameters = null;
406   
407  64 if (getBlockState().getListDepth() == 1) {
408  29 printEmptyLine();
409    } else {
410  35 getPrinter().print("\n");
411    }
412   
413  64 if (type == ListType.BULLETED) {
414  46 this.listStyle.append("*");
415    } else {
416  18 this.listStyle.append("1");
417    }
418  64 printParameters(parameters);
419    }
420   
 
421  94 toggle @Override
422    public void beginListItem()
423    {
424  94 if (getBlockState().getListItemIndex() > 0) {
425  30 getPrinter().print("\n");
426    }
427   
428  94 print(this.listStyle.toString());
429  94 if (StringUtils.contains(this.listStyle.toString(), '1')) {
430  32 print(".");
431    }
432  94 print(" ");
433    }
434   
 
435  64 toggle @Override
436    public void endList(ListType type, Map<String, String> parameters)
437    {
438  64 this.listStyle.setLength(this.listStyle.length() - 1);
439   
440    // Ensure that any not printed characters are flushed.
441    // TODO: Fix this better by introducing a state listener to handle escapes
442  64 getXWikiPrinter().flush();
443    }
444   
 
445  94 toggle @Override
446    public void endListItem()
447    {
448  94 this.previousFormatParameters = null;
449    }
450   
 
451  25 toggle @Override
452    public void beginMacroMarker(String name, Map<String, String> parameters, String content, boolean isInline)
453    {
454  25 if (!isInline) {
455  15 printEmptyLine();
456    }
457   
458    // When we encounter a macro marker we ignore all other blocks inside since we're going to use the macro
459    // definition wrapped by the macro marker to construct the xwiki syntax.
460  25 pushPrinter(new XWikiSyntaxEscapeWikiPrinter(VoidWikiPrinter.VOIDWIKIPRINTER, getXWikiSyntaxListenerChain()));
461    }
462   
 
463  25 toggle @Override
464    public void endMacroMarker(String name, Map<String, String> parameters, String content, boolean isInline)
465    {
466  25 this.previousFormatParameters = null;
467   
468  25 popPrinter();
469   
470  25 print(getMacroPrinter().renderMacro(name, parameters, content, isInline));
471    }
472   
 
473  6 toggle @Override
474    public void onId(String name)
475    {
476  6 print("{{id name=\"" + name + "\"/}}");
477    }
478   
 
479  10 toggle @Override
480    public void onHorizontalLine(Map<String, String> parameters)
481    {
482  10 printEmptyLine();
483  10 printParameters(parameters);
484  10 print("----");
485    }
486   
 
487  20 toggle @Override
488    public void onVerbatim(String content, boolean inline, Map<String, String> parameters)
489    {
490  20 if (!inline) {
491  10 printEmptyLine();
492    }
493  20 printParameters(parameters);
494   
495  20 print("{{{");
496  20 getXWikiPrinter().printVerbatimContent(content);
497  20 print("}}}");
498    }
499   
 
500  10 toggle @Override
501    public void onEmptyLines(int count)
502    {
503  10 print(StringUtils.repeat('\n', count));
504    }
505   
506    /**
507    * {@inheritDoc}
508    *
509    * @since 2.0RC1
510    */
 
511  22 toggle @Override
512    public void beginDefinitionList(Map<String, String> parameters)
513    {
514  22 if (getBlockState().getDefinitionListDepth() == 1 && !getBlockState().isInList()) {
515  14 printEmptyLine();
516    } else {
517  8 print("\n");
518    }
519  22 printParameters(parameters);
520    }
521   
522    /**
523    * {@inheritDoc}
524    *
525    * @since 1.6M2
526    */
 
527  17 toggle @Override
528    public void beginDefinitionTerm()
529    {
530  17 if (getBlockState().getDefinitionListItemIndex() > 0) {
531  2 getPrinter().print("\n");
532    }
533   
534  17 if (this.listStyle.length() > 0) {
535  2 print(this.listStyle.toString());
536  2 if (this.listStyle.charAt(0) == '1') {
537  1 print(".");
538    }
539    }
540  17 print(StringUtils.repeat(':', getBlockState().getDefinitionListDepth() - 1));
541  17 print("; ");
542    }
543   
544    /**
545    * {@inheritDoc}
546    *
547    * @since 1.6M2
548    */
 
549  21 toggle @Override
550    public void beginDefinitionDescription()
551    {
552  21 if (getBlockState().getDefinitionListItemIndex() > 0) {
553  14 getPrinter().print("\n");
554    }
555   
556  21 if (this.listStyle.length() > 0) {
557  2 print(this.listStyle.toString());
558  2 if (this.listStyle.charAt(0) == '1') {
559  1 print(".");
560    }
561    }
562  21 print(StringUtils.repeat(':', getBlockState().getDefinitionListDepth() - 1));
563  21 print(": ");
564    }
565   
 
566  21 toggle @Override
567    public void endDefinitionDescription()
568    {
569  21 this.previousFormatParameters = null;
570   
571  21 getXWikiPrinter().flush();
572    }
573   
 
574  17 toggle @Override
575    public void endDefinitionTerm()
576    {
577  17 this.previousFormatParameters = null;
578   
579  17 getXWikiPrinter().flush();
580    }
581   
582    /**
583    * {@inheritDoc}
584    *
585    * @since 1.6M2
586    */
 
587  11 toggle @Override
588    public void beginQuotation(Map<String, String> parameters)
589    {
590  11 if (!getBlockState().isInQuotationLine()) {
591  7 printEmptyLine();
592    }
593   
594  11 if (!parameters.isEmpty()) {
595  1 printParameters(parameters);
596    }
597    }
598   
599    /**
600    * {@inheritDoc}
601    *
602    * @since 1.6M2
603    */
 
604  17 toggle @Override
605    public void beginQuotationLine()
606    {
607  17 if (getBlockState().getQuotationLineIndex() > 0) {
608  10 getPrinter().print("\n");
609    }
610   
611  17 print(StringUtils.repeat('>', getBlockState().getQuotationDepth()));
612    }
613   
 
614  17 toggle @Override
615    public void endQuotationLine()
616    {
617  17 this.previousFormatParameters = null;
618   
619  17 getXWikiPrinter().flush();
620    }
621   
 
622  19 toggle @Override
623    public void beginTable(Map<String, String> parameters)
624    {
625  19 printEmptyLine();
626  19 if (!parameters.isEmpty()) {
627  2 printParameters(parameters);
628    }
629    }
630   
 
631  44 toggle @Override
632    public void beginTableCell(Map<String, String> parameters)
633    {
634  44 print("|");
635  44 printParameters(parameters, false);
636    }
637   
 
638  25 toggle @Override
639    public void beginTableHeadCell(Map<String, String> parameters)
640    {
641  25 print("|=");
642  25 printParameters(parameters, false);
643    }
644   
 
645  34 toggle @Override
646    public void beginTableRow(Map<String, String> parameters)
647    {
648  34 if (getBlockState().getCellRow() > 0) {
649  15 print("\n");
650    }
651   
652  34 printParameters(parameters, false);
653    }
654   
 
655  44 toggle @Override
656    public void endTableCell(Map<String, String> parameters)
657    {
658  44 this.previousFormatParameters = null;
659   
660    // Ensure that any not printed characters are flushed.
661    // TODO: Fix this better by introducing a state listener to handle escapes
662  44 getXWikiPrinter().flush();
663    }
664   
 
665  25 toggle @Override
666    public void endTableHeadCell(Map<String, String> parameters)
667    {
668  25 this.previousFormatParameters = null;
669    }
670   
671    /**
672    * {@inheritDoc}
673    *
674    * @since 2.5RC1
675    */
 
676  37 toggle @Override
677    public void onImage(ResourceReference reference, boolean freestanding, Map<String, String> parameters)
678    {
679  37 getImageRenderer().beginRenderLink(getXWikiPrinter(), reference, freestanding, parameters);
680  37 getImageRenderer().endRenderLink(getXWikiPrinter(), reference, freestanding, parameters);
681    }
682   
 
683  463 toggle protected void printParameters(Map<String, String> parameters)
684    {
685  463 printParameters(parameters, true);
686    }
687   
 
688  686 toggle protected void printParameters(Map<String, String> parameters, boolean newLine)
689    {
690  686 StringBuffer parametersStr = new StringBuffer();
691  686 for (Map.Entry<String, String> entry : parameters.entrySet()) {
692  103 String value = entry.getValue();
693  103 String key = entry.getKey();
694   
695  103 if (key != null && value != null) {
696    // Escape quotes in value to not break parameter value syntax
697  103 value = value.replaceAll("[~\"]", "~$0");
698    // Escape ending custom parameters syntax
699  103 value = value.replace("%)", "~%)");
700  103 parametersStr.append(' ').append(key).append('=').append('\"').append(value).append('\"');
701    }
702    }
703   
704  686 if (parametersStr.length() > 0) {
705  100 StringBuffer buffer = new StringBuffer("(%");
706  100 buffer.append(parametersStr);
707  100 buffer.append(" %)");
708   
709  100 if (newLine) {
710  24 buffer.append("\n");
711    }
712   
713  100 print(buffer.toString());
714    }
715    }
716   
 
717  1946 toggle private void printDelayed(String text)
718    {
719  1946 print(text, true);
720    }
721   
 
722  1180 toggle private void print(String text)
723    {
724  1180 print(text, false);
725    }
726   
 
727  3126 toggle private void print(String text, boolean isDelayed)
728    {
729    // Handle empty formatting parameters.
730  3126 if (this.previousFormatParameters != null) {
731  13 getPrinter().print("(%%)");
732  13 this.previousFormatParameters = null;
733    }
734   
735  3126 if (isDelayed) {
736  1946 getXWikiPrinter().printDelayed(text);
737    } else {
738  1180 getPrinter().print(text);
739    }
740    }
741   
 
742  482 toggle private void printEmptyLine()
743    {
744  482 if (this.isFirstElementRendered) {
745  176 print("\n\n");
746    } else {
747  306 this.isFirstElementRendered = true;
748    }
749    }
750   
751    /**
752    * {@inheritDoc}
753    *
754    * @since 2.0M3
755    */
 
756  363 toggle @Override
757    public void setPrinter(WikiPrinter printer)
758    {
759    // If the printer is already a XWiki Syntax Escape printer don't wrap it again. This case happens when
760    // the createChainingListenerInstance() method is called, ie when this renderer's state is stacked
761    // (for example when a Group event is being handled).
762  363 if (printer instanceof XWikiSyntaxEscapeWikiPrinter) {
763  29 super.setPrinter(printer);
764    } else {
765  334 super.setPrinter(new XWikiSyntaxEscapeWikiPrinter(printer, (XWikiSyntaxListenerChain) getListenerChain()));
766    }
767    }
768   
769    /**
770    * Allows exposing the additional methods of {@link XWikiSyntaxEscapeWikiPrinter}, namely the ability to delay
771    * printing some text and the ability to escape characters that would otherwise have a meaning in XWiki syntax.
772    */
 
773  4089 toggle public XWikiSyntaxEscapeWikiPrinter getXWikiPrinter()
774    {
775  4089 return (XWikiSyntaxEscapeWikiPrinter) super.getPrinter();
776    }
777   
 
778  115 toggle @Override
779    protected void popPrinter()
780    {
781    // Ensure that any not printed characters are flushed
782  115 getXWikiPrinter().flush();
783   
784  115 super.popPrinter();
785    }
786    }