jodd-core/src/main/java/jodd/template/StringTemplateParser.java
public String parse(String template, final Function<String, String> macroResolver) {
		StringBuilder result = new StringBuilder(template.length());

		int i = 0;
		int len = template.length();

		// strict flag means that start and end tag are not necessary
		boolean strict;

		if (macroPrefix == null) {
			// when prefix is not specified, make it equals to macro start
			// so we can use the same code
			macroPrefix = macroStart;

			strict = true;
		}
		else {
			strict = false;
		}

		final int prefixLen = macroPrefix.length();
		final int startLen = macroStart.length();
		final int endLen = macroEnd.length();

		while (i < len) {
			int ndx = template.indexOf(macroPrefix, i);
			if (ndx == -1) {
				result.append(i == 0 ? template : template.substring(i));
				break;
			}

			// check escaped
			int j = ndx - 1;
			boolean escape = false;
			int count = 0;

			while ((j >= 0) && (template.charAt(j) == escapeChar)) {
				escape = !escape;
				if (escape) {
					count++;
				}
				j--;
			}
			if (resolveEscapes) {
				result.append(template.substring(i, ndx - count));
			} else {
				result.append(template.substring(i, ndx));
			}
			if (escape) {
				result.append(macroPrefix);

				i = ndx + prefixLen;

				continue;
			}

			// macro started, detect strict format

			boolean detectedStrictFormat = strict;

			if (!detectedStrictFormat) {
				if (StringUtil.isSubstringAt(template, macroStart, ndx)) {
					detectedStrictFormat = true;
				}
			}

			int ndx1;
			int ndx2;

			if (!detectedStrictFormat) {
				// not strict format: $foo

				ndx += prefixLen;
				ndx1 = ndx;
				ndx2 = ndx;

				while ((ndx2 < len) && CharUtil.isPropertyNameChar(template.charAt(ndx2))) {
					ndx2++;
				}

				if (ndx2 == len) {
					ndx2--;
				}

				while ((ndx2 > ndx) && !CharUtil.isAlphaOrDigit(template.charAt(ndx2))) {
					ndx2--;
				}

				ndx2++;

				if (ndx2 == ndx1 + 1) {
					// no value, hence no macro
					result.append(macroPrefix);

					i = ndx1;
					continue;
				}
			}
			else {
				// strict format: ${foo}

				// find macros end
				ndx += startLen;
				ndx2 = template.indexOf(macroEnd, ndx);
				if (ndx2 == -1) {
					throw new IllegalArgumentException("Invalid template, unclosed macro at: " + (ndx - startLen));
				}

				// detect inner macros, there is no escaping
				ndx1 = ndx;
				while (ndx1 < ndx2) {
					int n = StringUtil.indexOf(template, macroStart, ndx1, ndx2);
					if (n == -1) {
						break;
					}
					ndx1 = n + startLen;
				}
			}

			final String name = template.substring(ndx1, ndx2);

			// find value and append

			Object value;
			if (missingKeyReplacement != null || !replaceMissingKey) {
				try {
					value = macroResolver.apply(name);
				} catch (Exception ignore) {
					value = null;
				}

				if (value == null) {
					if (replaceMissingKey) {
						value = missingKeyReplacement;
					} else {
						if (detectedStrictFormat) {
							value = template.substring(ndx1 - startLen, ndx2 + endLen);
						} else {
							value = template.substring(ndx1 - 1, ndx2);
						}
					}
				}
			} else {
				value = macroResolver.apply(name);
				if (value == null) {
					value = StringPool.EMPTY;
				}
			}

			if (ndx == ndx1) {
				String stringValue = value.toString();
				if (parseValues) {
					if (stringValue.contains(macroStart)) {
						stringValue = parse(stringValue, macroResolver);
					}
				}
				result.append(stringValue);

				i = ndx2;
				if (detectedStrictFormat) {
					i += endLen;
				}
			} else {
				// inner macro
				template = template.substring(0, ndx1 - startLen) + value.toString() + template.substring(ndx2 + endLen);
				len = template.length();
				i = ndx - startLen;
			}
		}
		return result.toString();
	}
public String parse(String template, final Function<String, String> macroResolver) {
		StringBuilder result = new StringBuilder(template.length());

		int i = 0;
		int len = template.length();

		// strict flag means that start and end tag are not necessary
		boolean strict;

		if (macroPrefix == null) {
			// when prefix is not specified, make it equals to macro start
			// so we can use the same code
			macroPrefix = macroStart;

			strict = true;
		}
		else {
			strict = false;
		}

		final int prefixLen = macroPrefix.length();
		final int startLen = macroStart.length();
		final int endLen = macroEnd.length();

		while (i < len) {
			int ndx = template.indexOf(macroPrefix, i);
			if (ndx == -1) {
				result.append(i == 0 ? template : template.substring(i));
				break;
			}

			// check escaped
			int j = ndx - 1;
			boolean escape = false;
			int count = 0;

			while ((j >= 0) && (template.charAt(j) == escapeChar)) {
				escape = !escape;
				if (escape) {
					count++;
				}
				j--;
			}
			if (resolveEscapes) {
				result.append(template.substring(i, ndx - count));
			} else {
				result.append(template.substring(i, ndx));
			}
			if (escape) {
				result.append(macroPrefix);

				i = ndx + prefixLen;

				continue;
			}

			// macro started, detect strict format

			boolean detectedStrictFormat = strict;

			if (!detectedStrictFormat) {
				if (StringUtil.isSubstringAt(template, macroStart, ndx)) {
					detectedStrictFormat = true;
				}
			}

			int ndx1;
			int ndx2;

			if (!detectedStrictFormat) {
				// not strict format: $foo

				ndx += prefixLen;
				ndx1 = ndx;
				ndx2 = ndx;

				while ((ndx2 < len) && CharUtil.isPropertyNameChar(template.charAt(ndx2))) {
					ndx2++;
				}

				if (ndx2 == len) {
					ndx2--;
				}

				while ((ndx2 > ndx) && !CharUtil.isAlphaOrDigit(template.charAt(ndx2))) {
					ndx2--;
				}

				ndx2++;

				if (ndx2 == ndx1 + 1) {
					// no value, hence no macro
					result.append(macroPrefix);

					i = ndx1;
					continue;
				}
			}
			else {
				// strict format: ${foo}

				// find macros end
				ndx += startLen;
				ndx2 = template.indexOf(macroEnd, ndx);
				if (ndx2 == -1) {
					throw new IllegalArgumentException("Invalid template, unclosed macro at: " + (ndx - startLen));
				}

				// detect inner macros, there is no escaping
				ndx1 = ndx;
				while (ndx1 < ndx2) {
					int n = StringUtil.indexOf(template, macroStart, ndx1, ndx2);
					if (n == -1) {
						break;
					}
					ndx1 = n + startLen;
				}
			}

			final String name = template.substring(ndx1, ndx2);

			// find value and append

			Object value;
			if (missingKeyReplacement != null || !replaceMissingKey) {
				try {
					value = macroResolver.apply(name);
				} catch (Exception ignore) {
					value = null;
				}

				if (value == null) {
					if (replaceMissingKey) {
						value = missingKeyReplacement;
					} else {
						if (detectedStrictFormat) {
							value = template.substring(ndx1 - startLen, ndx2 + endLen);
						} else {
							value = template.substring(ndx1 - 1, ndx2);
						}
					}
				}
			} else {
				value = macroResolver.apply(name);
				if (value == null) {
					value = StringPool.EMPTY;
				}
			}

			if (ndx == ndx1) {
				String stringValue = value.toString();
				if (parseValues) {
					if (stringValue.contains(macroStart)) {
						stringValue = parse(stringValue, macroResolver);
					}
				}
				result.append(stringValue);

				i = ndx2;
				if (detectedStrictFormat) {
					i += endLen;
				}
			} else {
				// inner macro
				template = template.substring(0, ndx1 - startLen) + value.toString() + template.substring(ndx2 + endLen);
				len = template.length();
				i = ndx - startLen;
			}
		}
		return result.toString();
	}
Parses string template and replaces macros with resolved values.