public List<String> getIncludedPages(XWikiContext context) { if (is10Syntax()) { return getIncludedPagesForXWiki10Syntax(getContent(), context); } else { // Find all include macros listed on the page XDOM dom = getXDOM(); List<String> result = new ArrayList<String>(); for (MacroBlock macroBlock : dom.getChildrenByType(MacroBlock.class, true)) { // - Add each document pointed to by the include macro // - Also add all the included pages found in the velocity macro when using the deprecated #include* // macros // This should be removed when we fully drop support for the XWiki Syntax 1.0 but for now we want to // play // nice with people migrating from 1.0 to 2.0 syntax if (macroBlock.getId().equalsIgnoreCase("include")) { String documentName = macroBlock.getParameters().get("document"); if (documentName.indexOf('.') == -1) { documentName = getSpace() + "." + documentName; } result.add(documentName); } else if (macroBlock.getId().equalsIgnoreCase("velocity") && !StringUtils.isEmpty(macroBlock.getContent())) { // Try to find matching content inside each velocity macro result.addAll(getIncludedPagesForXWiki10Syntax(macroBlock.getContent(), context)); } } return result; } }
/** * Wrap the output of a macro block with a {@link MacroMarkerBlock}. * * @param macroBlockToWrap the block that should be replaced * @param newBlocks list of blocks to wrap * @return the wrapper */ private Block wrapInMacroMarker(MacroBlock macroBlockToWrap, List<Block> newBlocks) { return new MacroMarkerBlock(macroBlockToWrap.getId(), macroBlockToWrap.getParameters(), macroBlockToWrap .getContent(), newBlocks, macroBlockToWrap.isInline()); }
/** * Wrap the output of a macro block with a {@link MacroMarkerBlock}. * * @param macroBlockToWrap the block that should be replaced * @param newBlocks list of blocks to wrap * @return the wrapper */ private Block wrapInMacroMarker(MacroBlock macroBlockToWrap, List<Block> newBlocks) { return new MacroMarkerBlock(macroBlockToWrap.getId(), macroBlockToWrap.getParameters(), macroBlockToWrap.getContent(), newBlocks, macroBlockToWrap.isInline()); }
/** * @param xdom the {@link XDOM} to convert * @return an inline version of the passed {@link XDOM} */ private XDOM convertToInline(XDOM xdom) { List<Block> blocks = new ArrayList<Block>(xdom.getChildren()); // TODO: use inline parser instead if (!blocks.isEmpty()) { this.parserUtils.removeTopLevelParagraph(blocks); // Make sure included macro is inline when script macro itself is inline Block block = blocks.get(0); if (block instanceof MacroBlock) { MacroBlock macro = (MacroBlock) block; if (!macro.isInline()) { blocks.set(0, new MacroBlock(macro.getId(), macro.getParameters(), macro.getContent(), true)); } } xdom.setChildren(blocks); } return xdom; }
/** * Wrap the output of a macro block with a {@link org.xwiki.rendering.block.MacroMarkerBlock}. * * @param macroBlockToWrap the block that should be replaced * @param newBlocks list of blocks to wrap * @return the wrapper */ private Block wrapInMacroMarker(MacroBlock macroBlockToWrap, List<Block> newBlocks) { return new MacroMarkerBlock(macroBlockToWrap.getId(), macroBlockToWrap.getParameters(), macroBlockToWrap.getContent(), newBlocks, macroBlockToWrap.isInline()); } }
/** * Clone and filter wiki macro content depending of the context. * * @param context the macro execution context * @return the cleaned wiki macro content */ private XDOM prepareWikiMacroContent() { XDOM xdom = this.wikimacro.getContent().clone(); // Macro code segment is always parsed into a separate xdom document. Now if this code segment starts with // another macro block, it will always be interpreted as a block macro regardless of the current wiki macro's // context (because as far as the nested macro is concerned, it starts on a new line). This will introduce // unnecessary paragraph elements when the wiki macro is used inline, so we need to force such opening macro // blocks to behave as inline macros if the wiki macro is used inline. if (this.inline) { List<Block> children = xdom.getChildren(); if (!children.isEmpty() && children.get(0) instanceof MacroBlock) { MacroBlock old = (MacroBlock) children.get(0); MacroBlock replacement = new MacroBlock(old.getId(), old.getParameters(), old.getContent(), true); xdom.replaceChild(replacement, old); } } return xdom; }
/** * {@inheritDoc} * * @see org.xwiki.rendering.block.AbstractBlock#traverse(org.xwiki.rendering.listener.Listener) */ public void traverse(Listener listener) { // Don't do anything here since we want the Macro Transformer component to take in charge // Macro execution. This is because Macro execution is a complex process that involves: // * computing the order in which the macros should be evaluated. For example the TOC macro // should evaluate last since other macros can contribute headers/sections blocks. // * some macros need to modify blocks in the XDOM object // * macro execution is a multi-pass process // In essence the Macro Transformer will replace all MacroBlock blocks with other Blocks // generated from the execution of the Macros when XDOM.traverse() is called there // won't be any MacroBlock.traverse() method called at all. // Note: We're calling the event to let other listener downstream decide what to do with it. // In practice as described above this method will never get called when the whole rendering // process is executed. This does get called during our unit tests though. listener.onMacro(getId(), getParameters(), getContent(), isInline()); } }
result.set(0, new MacroBlock(macro.getId(), macro.getParameters(), macro.getContent(), true));
result.set(0, new MacroBlock(macro.getId(), macro.getParameters(), macro.getContent(), true));
.getContent(), xdom.getChildren(), htmlMacroBlock.isInline());
htmlMacroBlock.getContent(), xdom.getChildren(), htmlMacroBlock.isInline());
newBlocks = ((Macro) macro).execute(macroParameters, macroBlock.getContent(), macroContext); } catch (Throwable e) {
((Macro<Object>) macroHolder.macro).execute(macroParameters, macroHolder.macroBlock.getContent(), context); } catch (Throwable e) {
wikiMacroBlock.getContent(), macroXDOM.getChildren(), wikiMacroBlock.isInline());