/*
 * utils - package-info.java - Copyright © 2010 David Roden
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Light-weight template system.
 *
 * <h3>Writing Templates</h3>
 *
 * <p>
 * Inserting values and control structures such as loops into a template uses
 * a syntax that is well-known by other preprocessors, such es PHP or JSPs.
 * For example:
 * </p>
 *
 * <pre>
 * <html>
 * <head>
 * <title>
 * <% title >
 * </title>
 * </head>
 * </html>
 * </pre>
 *
 * <p>
 * This will insert the value of the template variable named “title” into the
 * template.
 * </p>
 *
 * <h3>Setting Template Variables</h3>
 *
 * <p>
 * Variables in a template are set using the
 * {@link net.pterodactylus.util.template.Template#set(String, Object)} method.
 * </p>
 *
 * <pre>
 * Template template = new Template(new FileReader("template.html"));
 * template.set("variable", "value");
 * template.set("items", Arrays.asList("foo", "bar", "baz"));
 * template.render(outputWriter);
 * </pre>
 *
 * <h3>Looping Over Collections</h3>
 *
 * <p>
 * You can set the value of a template variable to an instance of
 * {@link java.util.Collection}. This allows you to iterate over the items in said collection:
 * </p>
 *
 * <pre>
 * <ul>
 * <%foreach pointCollection pointItem>
 * <li>
 * Item: <% pointItem>
 * </li>
 * <%/foreach>
 * </ul>
 * </pre>
 *
 * This will output the value of each item in the collection.
 *
 * <h3>Loop Properties</h3>
 *
 * <p>
 * Each iteration of a loop has numerous properties, such as being the first
 * iteration, or the last, or neither of them. These properties can be
 * accessed in a template.
 * </p>
 *
 * <pre>
 * <%foreach pointCollection pointItem>
 * <%first>
 * The collection contains the following items:
 * <ul>
 * <%/first>
 * <li>
 * Item: <% pointItem>
 * </li>
 * <%last>
 * </ul>
 * <%/last>
 * <%/foreach>
 * </pre>
 *
 * <p>
 * The loop properties that can be accessed in this way are: {@code first},
 * {@code last}, {@code notfirst}, {@code notlast}, {@code odd}, {@code even}.
 * </p>
 *
 * <h3>Item Properties</h3>
 *
 * <p>
 * Template variable names can specify a hierarchy: “item.index” specifies the
 * member “index” of the value of template variable “item”. The default
 * template implementation can only handle getting members of template
 * variables that contain instances of  {@link java.util.Map}; it is possible
 * to define member accessors for your own types (see below).
 * </p>
 *
 * <pre>
 * <ul>
 * <%foreach itemCollection item>
 * <li>
 * Item: <a href="item?id=<% item.id>"><% item.name></a>
 * </li>
 * <%/foreach>
 * </ul>
 * </pre>
 *
 * <p>
 * When {@code itemCollection} is properly set up this will print each item’s
 * name with a link to an item page that receives the ID of the item as
 * parameter. If {@code item} does not refer to a {@link java.util.Map} instance,
 * a custom accessor (see below) is necessary.
 * </p>
 *
 * <h3>Handling Custom Types</h3>
 *
 * <p>
 * The template system can be extended using
 * {@link net.pterodactylus.util.template.Accessor}s. An accessor is used to
 * allow template variable syntax like “object.foo”. Depending on the type of
 * {@code object}  the appropriate accessor is used to find the value of the
 * member “foo” (which can e.g. be retrieved by calling a complicated operation
 * on {@code object}).
 * </p>
 *
 * <p>
 * With a custom type {@code Item} that exposes both an ID and a name (using
 * {@code getID()} and {@code getName()} methods), the following
 * {@link net.pterodactylus.util.template.Accessor} will allow the above
 * example to work.
 * </p>
 *
 * <pre>
 * public class ItemAccessor implements Accessor {
 *     private final Item item;
 *     public ItemAccessor(Item item) { this.item = item; }
 *     public int getID() { return item.getID(); }
 *     public String getName() { return item.getName(); }
 * }
 * </pre>
 *
 * <h3>Conditional Execution</h3>
 *
 * <p>
 * With a loop and its constructs (e.g. <%first> or <%even>) you
 * can already shape your formatted text in quite some ways. If for some
 * reason this is not enough you do have another possibility.
 * </p>
 *
 * <pre>
 * <p>
 *     The color is:
 *     <%if color.black>
 *         black
 *     <%elseif color.red>
 *         red
 *     <%elseif ! color.green>
 *         not green
 *     <%else>
 *         green
 *     <%/if>
 * </p>
 * </pre>
 *
 * <p>
 * At the moment the {@code <%if>} directive requires a single argument
 * which has to evaluate to a {@link java.lang.Boolean} object. The object may
 * be prepended by an exclamation point (“!”, either with or without
 * whitespace following it) to signify that the condition should be reversed.
 * Using a custom accessor this can easily be accomplished. Any further
 * parsing (and expression evaluation) would make the template parser and
 * renderer almost infinitely more complex (and very not-light-weight-anymore).
 * </p>
 *
 * <h3>Filtering Output</h3>
 *
 * <p>
 * One large issue when handling text in web pages is escaping the HTML code
 * so that the content of a web page does not have the capability of inserting
 * custom code into a web site, or destroying its design by unbalanced tags.
 * The template supports filtering output but does not have any output filters
 * added to it by default.
 * </p>
 *
 * <pre>
 * Template template = new Template(templateReader);
 * template.addFilter("html", new HtmlFilter());
 * </pre>
 *
 * <p>
 * This will a filter for HTML to the list of available filters. If you want
 * to escape some text in your template, apply it using the pipe character
 * (“|”, with or without whitespace around it).
 * </p>
 *
 * <pre>
 * <div>Your name is <% name|html>, right?</div>
 * </pre>
 *
 * <p>
 * You can also use several filters for a single variable output. Those are
 * executed in the order they are specified.
 * </p>
 *
 * <pre>
 * <div>Your name is <% name|html|replace needle=Frank replacement=Steve>, right?</div>
 * </pre>
 *
 * <h3>Storing Values in the Template</h3>
 *
 * <p>
 * Sometimes it can be necessary to store a value in the template for later
 * use. In conjunction with a replacement filter this can be used to include
 * template variables in strings that are output by other filters, e.g. an
 * i18n filter.
 * </p>
 *
 * <pre>
 * <% user | html | store key='htmlUser'>
 * <% HelloText | i18n | html | insert needle='${user}' key='htmlUser'>
 * </pre>
 *
 * <p>
 * The “insert” filter can also read variables directly from the template.
 * </p>
 *
 * <h3>Internationalization / Localization (i18n, l10n)</h3>
 *
 * <p>
 * When creating web pages for larger projects you often have to deal with
 * multiple languages. One possibility to achieve multilingual support in a
 * template system would be to simply ignore language support in the template
 * system and create a new template for each language. However, this solution
 * is not desirable for any of the participating parties: the programmer has
 * to load a different template depending on the language; the designer has to
 * copy a desgin change into every translated template again; the translator
 * needs to copy and process a complete template, potentially missing
 * translatable items in a sea of design markup.
 * </p>
 *
 * <p>
 * One possible solution is the possibility to hardcode values in the template
 * and run them through arbitrary filters.
 * </p>
 *
 * <pre>
 * <div><%= Item.Name | i18n | html></div>
 * <div><% item.name | html></div>
 * <div><%= Item.ID | i18n | html></div>
 * <div><% item.id | html></div>
 * </pre>
 *
 * <p>
 * In this example the strings “Item.Name” and “Item.ID” are run through a
 * custom {@link net.pterodactylus.util.template.Filter} that replaces a
 * language-independent key into a translated string. To prevent nasty
 * surprises the translated string is also run through a HTML filter before
 * the final value is printed on the web page.
 * </p>
 *
 * <h3>Whitespace</h3>
 *
 * <p>
 * Sometimes, e.g. when using {@code <%=} or filters, whitespace in a filter
 * directive needs to be preserved. This can be accomplished by using single
 * quotes, double quotes, or a backslash.
 * </p>
 *
 * <h4>Single Quotes</h4>
 *
 * <p>
 * Single quotes preserve all characters until another single quote character
 * is encountered.
 * </p>
 *
 * <h4>Double Quotes</h4>
 *
 * <p>
 * Double quotes preserve all characters until either another double quote or
 * a backslash is encountered.
 * </p>
 *
 * <h4>Backslash</h4>
 *
 * <p>
 * The backslash preserves the next character but is discarded itself.
 * </p>
 *
 * <h4>Examples</h4>
 *
 * <pre>
 * <%= foo | replace needle=foo replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will replace the text “foo” with the text “bar baz”.
 * </p>
 *
 * <pre>
 * <%= "foo bar" | replace needle=foo replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will replace the text “foo bar” with the text “bar baz bar”.
 * </p>
 *
 * <pre>
 * <%= "foo bar" | replace needle='foo bar' replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will replace the text “foo bar” with the text “bar baz”.
 * </p>
 *
 * <pre>
 * <%= "foo bar" | replace needle=foo\ bar replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will also replace the text “foo bar” with the text “bar baz”.
 * </p>
 *
 * <pre>
 * <%= "foo bar" | replace needle="foo\ bar" replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will also replace the text “foo bar” with the text “bar baz”.
 * </p>
 *
 * <pre>
 * <%= "foo bar" | replace needle='foo\ bar' replacement="bar baz">
 * </pre>
 *
 * <p>
 * This will not replace the text “foo bar” with anything because the text
 * “foo\ bar” is not found.
 * </p>
 *
 */

package net.pterodactylus.util.template;