Return-Path: X-Original-To: apmail-freemarker-notifications-archive@minotaur.apache.org Delivered-To: apmail-freemarker-notifications-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 06E42181C6 for ; Wed, 30 Dec 2015 18:11:34 +0000 (UTC) Received: (qmail 30545 invoked by uid 500); 30 Dec 2015 18:11:34 -0000 Delivered-To: apmail-freemarker-notifications-archive@freemarker.apache.org Received: (qmail 30524 invoked by uid 500); 30 Dec 2015 18:11:33 -0000 Mailing-List: contact notifications-help@freemarker.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@freemarker.incubator.apache.org Delivered-To: mailing list notifications@freemarker.incubator.apache.org Received: (qmail 30515 invoked by uid 99); 30 Dec 2015 18:11:33 -0000 Received: from Unknown (HELO spamd3-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Dec 2015 18:11:33 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd3-us-west.apache.org (ASF Mail Server at spamd3-us-west.apache.org) with ESMTP id 65C7C1804FB for ; Wed, 30 Dec 2015 18:11:33 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd3-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 1.247 X-Spam-Level: * X-Spam-Status: No, score=1.247 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-0.554, URIBL_BLOCKED=0.001] autolearn=disabled Received: from mx1-eu-west.apache.org ([10.40.0.8]) by localhost (spamd3-us-west.apache.org [10.40.0.10]) (amavisd-new, port 10024) with ESMTP id 9kR26bpZJgc4 for ; Wed, 30 Dec 2015 18:11:25 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-eu-west.apache.org (ASF Mail Server at mx1-eu-west.apache.org) with SMTP id C5E61215DD for ; Wed, 30 Dec 2015 18:11:22 +0000 (UTC) Received: (qmail 29331 invoked by uid 99); 30 Dec 2015 18:11:21 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Dec 2015 18:11:21 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id B7C6FE0B19; Wed, 30 Dec 2015 18:11:21 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ddekany@apache.org To: notifications@freemarker.incubator.apache.org Date: Wed, 30 Dec 2015 18:11:29 -0000 Message-Id: In-Reply-To: <5bc2e3812f964818b5fa5a690376afc9@git.apache.org> References: <5bc2e3812f964818b5fa5a690376afc9@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [09/35] incubator-freemarker git commit: Output format and escaping related typos and minor adjustments in JavaDoc and Manual Output format and escaping related typos and minor adjustments in JavaDoc and Manual Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/aa53f15d Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/aa53f15d Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/aa53f15d Branch: refs/heads/2.3 Commit: aa53f15d3df1440a4f1349796e1082b33950913d Parents: d5c2d14 Author: ddekany Authored: Mon Dec 21 17:50:41 2015 +0100 Committer: ddekany Committed: Mon Dec 21 17:50:41 2015 +0100 ---------------------------------------------------------------------- .../freemarker/core/MarkupOutputFormat.java | 26 ++++--- src/main/java/freemarker/core/OutputFormat.java | 35 +++++---- .../freemarker/core/TemplateConfiguration.java | 4 +- .../core/TemplateMarkupOutputModel.java | 15 ++-- .../java/freemarker/template/Configuration.java | 37 +++++----- src/manual/en_US/book.xml | 75 ++++++++++---------- 6 files changed, 104 insertions(+), 88 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/main/java/freemarker/core/MarkupOutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/MarkupOutputFormat.java b/src/main/java/freemarker/core/MarkupOutputFormat.java index 784c8e5..0f1302c 100644 --- a/src/main/java/freemarker/core/MarkupOutputFormat.java +++ b/src/main/java/freemarker/core/MarkupOutputFormat.java @@ -25,8 +25,12 @@ import freemarker.template.TemplateModelException; /** * An {@link OutputFormat}-s that represent a "markup", which is any format where certain character sequences have - * special meaning and thus may need escaping. Escaping is important for FreeMarker, as typically it has to insert - * non-markup data from the data-model. + * special meaning and thus may need escaping. (Escaping is important for FreeMarker, as typically it has to insert + * non-markup text from the data-model into the output markup.) This class, among others, defines the operations related + * to {@link TemplateMarkupOutputModel}-s that belong to the output format. + * + * @param + * The {@link TemplateMarkupOutputModel} class this output format can deal with. * * @since 2.3.24 */ @@ -47,7 +51,7 @@ public abstract class MarkupOutputFormat e public abstract MO fromPlainTextByEscaping(String textToEsc) throws TemplateModelException; /** - * Wraps {@link String} that's already markup to {@link TemplateMarkupOutputModel} interface, to indicate its + * Wraps a {@link String} that's already markup to {@link TemplateMarkupOutputModel} interface, to indicate its * format. This corresponds to {@code ?noEsc}. (This methods is allowed to throw {@link TemplateModelException} if * the parameter markup text is malformed, but it's unlikely that an implementation chooses to parse the parameter * until, and if ever, that becomes necessary.) @@ -63,14 +67,15 @@ public abstract class MarkupOutputFormat e /** * Equivalent to calling {@link #fromPlainTextByEscaping(String)} and then - * {@link #output(TemplateMarkupOutputModel, Writer)}, but implementators should chose a more efficient way. + * {@link #output(TemplateMarkupOutputModel, Writer)}, but the implementation may uses a more efficient solution. */ public abstract void output(String textToEsc, Writer out) throws IOException, TemplateModelException; /** * If this {@link TemplateMarkupOutputModel} was created with {@link #fromPlainTextByEscaping(String)}, it returns - * the original plain text, otherwise it might returns {@code null}. Used when converting between different type of - * markups and the source was made from plain text. + * the original plain text, otherwise it returns {@code null}. Useful for converting between different types + * of markups, as if the source format can be converted to plain text without loss, then that just has to be + * re-escaped with the target format to do the conversion. */ public abstract String getSourcePlainText(MO mo) throws TemplateModelException; @@ -78,7 +83,7 @@ public abstract class MarkupOutputFormat e * Returns the content as markup text; never {@code null}. If this {@link TemplateMarkupOutputModel} was created * with {@link #fromMarkup(String)}, it might returns the original markup text literally, but this is not required * as far as the returned markup means the same. If this {@link TemplateMarkupOutputModel} wasn't created - * with {@link #fromMarkup(String)} and it doesn't yet have to markup, it has to generate the markup now. + * with {@link #fromMarkup(String)} and it doesn't yet have the markup, it has to generate the markup now. */ public abstract String getMarkupString(MO mo) throws TemplateModelException; @@ -90,12 +95,12 @@ public abstract class MarkupOutputFormat e /** * Should give the same result as {@link #fromPlainTextByEscaping(String)} and then - * {@link #getMarkupString(TemplateMarkupOutputModel)}, but the implementation may uses a more efficient approach. + * {@link #getMarkupString(TemplateMarkupOutputModel)}, but the implementation may uses a more efficient solution. */ public abstract String escapePlainText(String plainTextContent) throws TemplateModelException; /** - * Returns if the markup is empty (0 length). This is used be at least {@code ?hasContent}. + * Returns if the markup is empty (0 length). This is used by at least {@code ?hasContent}. */ public abstract boolean isEmpty(MO mo) throws TemplateModelException; @@ -107,7 +112,8 @@ public abstract class MarkupOutputFormat e public abstract boolean isLegacyBuiltInBypassed(String builtInName) throws TemplateModelException; /** - * Usually {@code true}; tells if by default auto-escaping should be on for this format. + * Tells if by default auto-escaping should be on for this format. It should be {@code true} if you need to escape + * on most of the places where you insert values. */ public abstract boolean isAutoEscapedByDefault(); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/main/java/freemarker/core/OutputFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/OutputFormat.java b/src/main/java/freemarker/core/OutputFormat.java index 05495ca..72ea821 100644 --- a/src/main/java/freemarker/core/OutputFormat.java +++ b/src/main/java/freemarker/core/OutputFormat.java @@ -18,39 +18,44 @@ */ package freemarker.core; +import freemarker.template.Configuration; import freemarker.template.utility.ClassUtil; import freemarker.template.utility.StringUtil; /** - * Encapsulates the {@link TemplateMarkupOutputModel} factories and {@code TemplateOutputModel} operations, and other - * meta information (like MIME type) about a certain output format. + * Represents an output format. + * + * @see Configuration#setOutputFormat(OutputFormat) + * @see Configuration#setRegisteredCustomOutputFormats(java.util.Collection) + * @see MarkupOutputFormat * * @since 2.3.24 */ public abstract class OutputFormat { /** - * The short name we used to refer to this format (like in the {@code #ftl} header). + * The short name used to refer to this format (like in the {@code #ftl} header). */ public abstract String getName(); /** - * Returns the MIME type of the output format. This might comes handy when generating generating a HTTP response. - * {@code null} if the output format doesn't clearly corresponds to a specific MIME type. + * Returns the MIME type of the output format. This might comes handy when generating a HTTP response. {@code null} + * if this output format doesn't clearly corresponds to a specific MIME type. */ public abstract String getMimeType(); /** - * Tells if this output format allows inserting {@link TemplateMarkupOutputModel}-s of another output formats into it. If - * {@code true}, the foreign {@link TemplateMarkupOutputModel} will be inserted into the output as is (like if the - * surrounding output format was the same). This is usually a bad idea, as such an even could indicate application - * bugs. If this method returns {@code false} (recommended), then FreeMarker will try to assimilate the inserted - * value by converting its format to this format, which will currently (2.3.24) cause exception, unless the inserted - * value is made by escaping plain text and the target format is not escaping, in which case format conversion is - * trivially possible. (It's not impossible to extending conversions beyond this, if there will be real world demand - * for it.) + * Tells if this output format allows inserting {@link TemplateMarkupOutputModel}-s of another output formats into + * it. If {@code true}, the foreign {@link TemplateMarkupOutputModel} will be inserted into the output as is (like + * if the surrounding output format was the same). This is usually a bad idea allow, as such an event could indicate + * application bugs. If this method returns {@code false} (recommended), then FreeMarker will try to assimilate the + * inserted value by converting its format to this format, which will currently (2.3.24) cause exception, unless the + * inserted value is made by escaping plain text and the target format is non-escaping, in which case format + * conversion is trivially possible. (It's not impossible that conversions will be extended beyond this, if there + * will be demand for that.) * - *

{@code true} value is used by {@link UndefinedOutputFormat}. + *

+ * {@code true} value is used by {@link UndefinedOutputFormat}. */ public abstract boolean isOutputFormatMixingAllowed(); @@ -70,7 +75,7 @@ public abstract class OutputFormat { /** * Should be like {@code "foo=\"something\", bar=123"}; this will be inserted inside the parentheses in - * {@link #toString()}. + * {@link #toString()}. Shouldn't return {@code null}; should return {@code ""} if there are no extra properties. */ protected String toStringExtraProperties() { return ""; http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/main/java/freemarker/core/TemplateConfiguration.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/TemplateConfiguration.java b/src/main/java/freemarker/core/TemplateConfiguration.java index 310028f..2c89d01 100644 --- a/src/main/java/freemarker/core/TemplateConfiguration.java +++ b/src/main/java/freemarker/core/TemplateConfiguration.java @@ -114,8 +114,8 @@ public final class TemplateConfiguration extends Configurable implements ParserC if (((Configuration) cfg).getIncompatibleImprovements().intValue() < _TemplateAPI.VERSION_INT_2_3_22 && hasAnyConfigurableSet()) { throw new IllegalStateException( - "This TemplateConfiguration can't be associated to a Configuration that has incompatibleImprovements " - + "less than 2.3.22, because it changes non-parser settings."); + "This TemplateConfiguration can't be associated to a Configuration that has " + + "incompatibleImprovements less than 2.3.22, because it changes non-parser settings."); } super.setParent(cfg); http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/main/java/freemarker/core/TemplateMarkupOutputModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/TemplateMarkupOutputModel.java b/src/main/java/freemarker/core/TemplateMarkupOutputModel.java index 4713f5b..3606379 100644 --- a/src/main/java/freemarker/core/TemplateMarkupOutputModel.java +++ b/src/main/java/freemarker/core/TemplateMarkupOutputModel.java @@ -26,14 +26,15 @@ import freemarker.template.TemplateScalarModel; * "markup output" template language data-type; stores markup (some kind of "rich text" / structured format, as opposed * to plain text) that meant to be printed as template output. Each implementation of this type has a * {@link OutputFormat} subclass pair (like {@link TemplateHTMLOutputModel} has {@link HTMLOutputFormat}). This type is - * related to the {@link Configuration#setOutputFormat(OutputFormat)} and {@link Configuration#setAutoEscapingPolicy(int)} - * mechanism; see more there. Values of this type are exempt from automatic escaping with that mechanism. + * related to the {@link Configuration#setOutputFormat(OutputFormat)} and + * {@link Configuration#setAutoEscapingPolicy(int)} mechanism; see more there. Values of this type are exempt from + * automatic escaping with that mechanism. * - *

Note that {@link TemplateMarkupOutputModel}-s are by design not handled like {@link TemplateScalarModel}-s, - * and so the implementations of this interface usually shouldn't implement {@link TemplateScalarModel}. (Because, - * operations applicable on plain strings, like converting to upper case, substringing, etc., can corrupt markup.) - * The template author should make conscious decision of passing in the markup as String by using - * {@code ?markup_string}. + *

+ * Note that {@link TemplateMarkupOutputModel}-s are by design not handled like {@link TemplateScalarModel}-s, and so + * the implementations of this interface usually shouldn't implement {@link TemplateScalarModel}. (Because, operations + * applicable on plain strings, like converting to upper case, substringing, etc., can corrupt markup.) The template + * author should make conscious decision of passing in the markup as String by using {@code ?markup_string}. * * @param * Refers to the interface's own type, which is useful in interfaces that extend http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/main/java/freemarker/template/Configuration.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/Configuration.java b/src/main/java/freemarker/template/Configuration.java index 0e67121..4199458 100644 --- a/src/main/java/freemarker/template/Configuration.java +++ b/src/main/java/freemarker/template/Configuration.java @@ -1794,13 +1794,13 @@ public class Configuration extends Configurable implements Cloneable, ParserConf /** * Sets the (default) output format. Usually, you leave this on its default, which is * {@link UndefinedOutputFormat#INSTANCE}, and then override it for individual templates based on their name (like - * based on their "file" extension) with {@link #setTemplateConfigurations(TemplateConfigurationFactory)}. This setting is - * also overridden by the standard file extensions; see them at + * based on their "file" extension) with {@link #setTemplateConfigurations(TemplateConfigurationFactory)}. This + * setting is also overridden by the standard file extensions; see them at * {@link #setRecognizeStandardFileExtensions(boolean)}. * *

- * The output format is mostly important because of auto-escaping (see {@link #setAutoEscapingPolicy(int)}), but maybe - * also used by the embedding application to set the HTTP response MIME type, etc. + * The output format is mostly important because of auto-escaping (see {@link #setAutoEscapingPolicy(int)}), but + * maybe also used by the embedding application to set the HTTP response MIME type, etc. * * @see #setRegisteredCustomOutputFormats(Collection) * @see #setTemplateConfigurations(TemplateConfigurationFactory) @@ -1854,19 +1854,23 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } /** - * Returns the output format for a name (not {@code null}). + * Returns the output format for a name. * - *

- * The name can also refer to a combined format that's created ad-hoc from the registered formats. For example, if - * you need RTF embedded into HTML, the name will be HTML{RTF}, where "HTML" and "RTF" refer to the - * existing formats. This logic can be used recursively, so for example XML{HTML{RTF}} is also valid. + * @param name + * Either the name of the output format as it was registered with + * {@link Configuration#setRegisteredCustomOutputFormats(Collection)}, or a combined output format name. + * A output combined format is created ad-hoc from the registered formats. For example, if you need RTF + * embedded into HTML, the name will be HTML{RTF}, where "HTML" and "RTF" refer to the + * existing formats. This logic can be used recursively, so for example XML{HTML{RTF}} is + * also valid. + * + * @return Not {@code null}. * * @throws UnregisteredOutputFormatException * If there's no output format registered with the given name. * @throws IllegalArgumentException - * If the usage of { and } in the name is syntactically wrong, or if not - * all {@link OutputFormat}-s are {@link MarkupOutputFormat}-s in the ...{...} - * expression. + * If the usage of { and } in the name is syntactically wrong, or if not all + * {@link OutputFormat}-s are {@link MarkupOutputFormat}-s in the ...{...} expression. * * @since 2.3.24 */ @@ -1882,7 +1886,8 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } MarkupOutputFormat outerOF = getMarkupOutputFormatForCombined(name.substring(0, openBrcIdx)); - MarkupOutputFormat innerOF = getMarkupOutputFormatForCombined(name.substring(openBrcIdx + 1, name.length() - 1)); + MarkupOutputFormat innerOF = getMarkupOutputFormatForCombined( + name.substring(openBrcIdx + 1, name.length() - 1)); return new CombinedMarkupOutputFormat(name, outerOF, innerOF); } else { @@ -1943,8 +1948,8 @@ public class Configuration extends Configurable implements Cloneable, ParserConf * The default value is an empty collection. * * @param registeredCustomOutputFormats - * The collection of the {@link OutputFormat}-s, each must be different and has a unique name within this - * collection. + * The collection of the {@link OutputFormat}-s, each must be different and has a unique name ( + * {@link OutputFormat#getName()}) within this collection. * * @throws IllegalArgumentException * When multiple different {@link OutputFormat}-s have the same name in the parameter collection. When @@ -2002,7 +2007,7 @@ public class Configuration extends Configurable implements Cloneable, ParserConf } this.registeredCustomOutputFormats = Collections.unmodifiableMap(m); - cache.clear(); + clearTemplateCache(); } /** http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/aa53f15d/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index ce8137e..acfead4 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -913,9 +913,9 @@ All Rights Reserved. extension to activate XML auto-escaping. You can try if auto-escaping is on like - ${"<"} (for HTML or XML escaping). If it's - not, and the configuration won't be adjusted, add this as the very - first line of the template: + ${"<"} and then checking the raw output (for + HTML or XML escaping). If it's not, and the configuration won't be + adjusted, add this as the very first line of the template: <#ftl output_format="HTML"> @@ -5282,7 +5282,7 @@ jsmith@other.com, jsmith@other.com, jsmith@other.com literal. It also specifies a MIME type (e.g. "text/HTML") and a canonical name (e.g. "HTML") that the embedding application/framework - can leverage for its own purposes. + can use for its own purposes. It's the programmer's responsibility to associate output format @@ -5318,7 +5318,7 @@ jsmith@other.com, jsmith@other.com, jsmith@other.com &gt;, &amp;, &#39; - text/HTML + text/html HTMLOutputFormat.INSTANCE @@ -5370,8 +5370,7 @@ jsmith@other.com, jsmith@other.com, jsmith@other.com plainText Doesn't escape. Doesn't accept markup output values from - other output formats. The output format inside string - literals. + other output formats. text/plain @@ -5380,9 +5379,8 @@ jsmith@other.com, jsmith@other.com, jsmith@other.com - The programmers can extend this with their your own output - formats, so this is maybe not all the output formats in your - application! + The programmers can add their your own output formats, so this + is maybe not all the output formats in your application!

@@ -5412,7 +5410,7 @@ ${"'"} <#-- Prints: &apos; --> output_format="XML" auto_esc=true> might helps (and that means that FreeMarker was configured to use disable auto-escaping policy, - which is usually not recommended). + which is generally not recommended). The output format can also be applied to only a section of a @@ -5431,16 +5429,16 @@ ${"'"} <#-- Prints: &#39; --> everywhere in the template. This association sticks to the positions and won't change as the template executes. So if, for example, you call a macro from inside an outputformat block - that's defined outside that block, it won't get the output format of - it. Or, if you have a macro that's defined in a template with HTML - output format, no mater from where you call it, that macro will - always execute with HTML output format. This is like if you were - coloring each characters of the template files by output format in - the text editor, and then later when the templates are executed, it - only considers the color of the statement being executed. This gives - you firm control over the output format and hence escaping; you - don't have to consider the possible execution paths that can lead to - a point. + and the called macro is defined outside that block, it won't get the + output format of it. Or, if you have a macro that's defined in a + template with HTML output format, no mater from where you call it, + that macro will always execute with HTML output format. This is like + if you were coloring each characters of the template files by output + format in the text editor, and then later when the templates are + executed, it only considers the color of the statement being + executed. This gives you firm control over the output format and + hence escaping; you don't have to consider the possible execution + paths that can lead to a point.
@@ -5494,7 +5492,7 @@ ${'&'} <#-- prints: & --> ${'&'} <#-- prints: & --> ${'&'?esc} <#-- prints: &amp; --> - Of course, both autoesc and + Naturally, both autoesc and ?esc works inside noautoesc blocks too.
@@ -5502,7 +5500,7 @@ ${'&'?esc} <#-- prints: &amp; --> <quote>Markup output</quote> values - In FTL, values has + In FTL, values have type, like string, number, boolean, etc. One such type is called markup output. A value of that type is a piece of text that's already in the output format (like HTML), and hence @@ -5524,11 +5522,11 @@ ${'&'?esc} <#-- prints: &amp; --> - Hence these can be used outside + These can be useful outside ${...} too. For example, here the caller of the infoBox macro can - decide if the message is plain text (that so needs escaping) or HTML - (that so mustn't be escaped): + decide if the message is plain text (hence needs escaping) or HTML + (hence it mustn't be escaped): <#-- We assume that we have "HTML" output format by default. --> @@ -5559,7 +5557,7 @@ Captured output: ${captured} Just a string: &lt;b&gt;Test&lt;/b&gt; Captured output: <b>Test</b> - Because the captured output is markup output it wasn't + Because the captured output is markup output, it wasn't auto-escaped. It's important that markup output values aren't strings, and @@ -5568,7 +5566,7 @@ Captured output: <b>Test</b> etc., will give an error with them. You won't be able to pass them to Java methods for String parameters either. But sometimes you need the markup that's behind the value as a string, - and you can get that as + which you can get as markupOutput?markup_string. Be sure you know what you are doing though. Applying string operations on markup (as opposed to on plain text) can result in @@ -5584,7 +5582,7 @@ As expected: ${markupOutput1} ${markupOutput2} -Double escaping: +Possibly unintended double escaping: ${markupOutput1?markup_string} ${markupOutput2?markup_string} @@ -5592,7 +5590,7 @@ ${markupOutput2?markup_string} <b>Test</b> Foo &amp; bar -Double escaping: +Possibly unintended double escaping: &lt;b&gt;Test&lt;/b&gt; Foo &amp;amp; bar @@ -5667,10 +5665,11 @@ RTF: Failed that, which is the output format used for templates for which no output format was specified in the configuration: - <#outputformat "HTML"><#assign htmlMO><p>Test</#assign></#outputformat> + <#-- We assume that we have "undefined" output format here. --> + +<#outputformat "HTML"><#assign htmlMO><p>Test</#assign></#outputformat> <#outputformat "XML"><#assign xmlMO><p>Test</p></#assign></#outputformat> <#outputformat "RTF"><#assign rtfMO>\par Test</#assign></#outputformat> -<#-- We assume that we have "undefined" output format here. --> HTML: ${htmlMO} XML: ${xmlMO} RTF: ${rtfMO} @@ -5692,7 +5691,7 @@ RTF: \par Test value in one side, the other side gets promoted to markup output value of the same output format (if it's not already that), by escaping its string value, and finally the two markups are - concatenated to form a new markup value. Example: + concatenated to form a new markup output value. Example: <#-- We assume that we have "HTML" output format by default. --> ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc} @@ -5703,8 +5702,8 @@ ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc} markup values of different output formats, the right side operand is converted to the output format of the left side. If that's not possible, then the left side operand is converted to the output - format of the right side. If that wasn't possible either, that's - an error. (See the limitations of conversions here.) @@ -5717,8 +5716,8 @@ ${"<h1>"?no_esc + "Foo & bar" + "</h1>"?no_esc} <#assign s = "Hello ${name}!">), it's just a shorthand of using the + operator (<#assign s = "Hello" + name + "!">). - Thus, ${...} inside - string expressions isn't auto-escaped. + Thus, ${...}-s + inside string expressions aren't auto-escaped. <#-- We assume that we have "HTML" output format by default. --> <#assign name = "Foo & Bar"> @@ -5733,7 +5732,7 @@ ${s?replace('&'), 'and'} &lt;p&gt;Hello Foo &amp; Bar! <p>Hello Foo &amp; Bar! -To prove that s didn't contain the value in escaped form: +To prove that "s" didn't contain the value in escaped form: &lt;p&gt;Hello Foo and Bar!