You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2020/07/12 00:14:58 UTC
[freemarker-docgen] 04/09: Split to multiple Maven modules.
This is an automated email from the ASF dual-hosted git repository.
ddekany pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/freemarker-docgen.git
commit 0465760014522eb4a12ba94f32f17fe4f3ce168a
Author: ddekany <dd...@apache.org>
AuthorDate: Fri Jul 10 01:49:46 2020 +0200
Split to multiple Maven modules.
---
.gitignore | 1 +
README.md | 17 +-
freemarker-docgen-ant/pom.xml | 68 +
.../org/freemarker/docgen/TransformAntTask.java | 0
.../org/freemarker/docgen/antlib.properties | 0
freemarker-docgen-cli/pom.xml | 72 +
.../freemarker/docgen/TransformCommandLine.java | 0
.../gulp-output-copyright-header.txt | 0
gulpfile.js => freemarker-docgen-core/gulpfile.js | 0
.../package-lock.json | 0
.../package.json | 0
pom.xml => freemarker-docgen-core/pom.xml | 75 +-
.../java/org/freemarker/docgen/BugException.java | 0
.../org/freemarker/docgen/CJSONInterpreter.java | 0
.../freemarker/docgen/CollectingErrorHandler.java | 0
.../docgen/CommandLineExitException.java | 0
.../org/freemarker/docgen/DocBook5Constants.java | 0
.../org/freemarker/docgen/DocgenException.java | 0
.../java/org/freemarker/docgen/DocgenLogger.java | 0
.../docgen/DocgenRestrictionsValidator.java | 0
.../freemarker/docgen/DocgenValidationOptions.java | 0
.../main/java/org/freemarker/docgen/FileUtil.java | 0
.../src}/main/java/org/freemarker/docgen/Logo.java | 0
.../docgen/MessageStreamActivityMonitor.java | 0
.../org/freemarker/docgen/RelaxNGValidator.java | 0
.../org/freemarker/docgen/TableSimplifier.java | 0
.../main/java/org/freemarker/docgen/TextUtil.java | 0
.../main/java/org/freemarker/docgen/Transform.java | 0
.../freemarker/docgen/ValidatingDOMBuilder.java | 0
.../docgen/ValidatingDOMBuilderWithLocations.java | 0
.../main/java/org/freemarker/docgen/XMLUtil.java | 0
.../src}/main/java/overview.html | 0
.../org/freemarker/docgen/js/make-toc.js | 0
.../org/freemarker/docgen/js/page-menu.js | 0
.../org/freemarker/docgen/js/search.js | 0
.../org/freemarker/docgen/js/use-strict.js | 0
.../org/freemarker/docgen/less/lib/base.less | 0
.../docgen/less/lib/components/bookmarks.less | 0
.../docgen/less/lib/components/breadcrumb.less | 0
.../docgen/less/lib/components/callout.less | 0
.../docgen/less/lib/components/code-block.less | 0
.../docgen/less/lib/components/logo.less | 0
.../docgen/less/lib/components/marked-text.less | 0
.../docgen/less/lib/components/page-menu.less | 0
.../docgen/less/lib/components/pagers.less | 0
.../docgen/less/lib/components/search-form.less | 0
.../docgen/less/lib/components/search-results.less | 0
.../docgen/less/lib/components/secondary-tabs.less | 0
.../docgen/less/lib/components/social-icons.less | 0
.../less/lib/components/table-of-contents.less | 0
.../docgen/less/lib/components/table.less | 0
.../docgen/less/lib/components/tabs.less | 0
.../org/freemarker/docgen/less/lib/icons.less | 0
.../freemarker/docgen/less/lib/layout/content.less | 0
.../freemarker/docgen/less/lib/layout/footer.less | 0
.../freemarker/docgen/less/lib/layout/header.less | 0
.../org/freemarker/docgen/less/lib/mixins.less | 0
.../org/freemarker/docgen/less/lib/utilities.less | 0
.../org/freemarker/docgen/less/lib/variables.less | 0
.../org/freemarker/docgen/less/styles.less | 0
.../org/freemarker/docgen/schema/docbook.rng | 0
.../org/freemarker/docgen/statics/fonts/NOTICE | 0
.../freemarker/docgen/statics/fonts/icomoon.eot | Bin
.../freemarker/docgen/statics/fonts/icomoon.svg | 0
.../freemarker/docgen/statics/fonts/icomoon.ttf | Bin
.../freemarker/docgen/statics/fonts/icomoon.woff | Bin
.../freemarker/docgen/statics/fonts/selection.json | 0
.../freemarker/docgen/statics/img/patterned-bg.png | Bin
.../org/freemarker/docgen/statics/img/xxe.gif | Bin
.../org/freemarker/docgen/statics/img/xxe.png | Bin
.../docgen/templates/customizations.ftlh | 0
.../freemarker/docgen/templates/eclipse-toc.ftlx | 0
.../org/freemarker/docgen/templates/footer.ftlh | 0
.../org/freemarker/docgen/templates/google.ftlh | 0
.../org/freemarker/docgen/templates/header.ftlh | 0
.../freemarker/docgen/templates/navigation.ftlh | 0
.../freemarker/docgen/templates/node-handlers.ftlh | 0
.../org/freemarker/docgen/templates/page.ftlh | 0
.../org/freemarker/docgen/templates/sitemap.ftlx | 0
.../org/freemarker/docgen/templates/toc-json.ftl | 0
.../org/freemarker/docgen/templates/util.ftl | 0
freemarker-docgen-maven/pom.xml | 59 +
.../java/org/freemarker/docgen/TransformMojo.java | 0
legacy-tests/README | 4 +
test.xml => legacy-tests/build.xml | 27 +-
legacy-tests/build/test/1/alphaidx.html | 1281 +
legacy-tests/build/test/1/app.html | 45 +
legacy-tests/build/test/1/app_build.html | 58 +
legacy-tests/build/test/1/app_faq.html | 1686 ++
legacy-tests/build/test/1/app_install.html | 99 +
legacy-tests/build/test/1/app_license.html | 92 +
legacy-tests/build/test/1/app_versions.html | 45 +
{src => legacy-tests/build}/test/1/bat.jpg | Bin
legacy-tests/build/test/1/detailed-toc.html | 69 +
legacy-tests/build/test/1/dgui.html | 45 +
legacy-tests/build/test/1/dgui_datamodel.html | 45 +
.../build/test/1/dgui_datamodel_basics.html | 221 +
.../build/test/1/dgui_datamodel_types.html | 458 +
legacy-tests/build/test/1/dgui_misc.html | 45 +
.../build/test/1/dgui_misc_alternativesyntax.html | 110 +
legacy-tests/build/test/1/dgui_misc_namespace.html | 340 +
.../build/test/1/dgui_misc_userdefdir.html | 530 +
legacy-tests/build/test/1/dgui_misc_var.html | 161 +
.../build/test/1/dgui_misc_whitespace.html | 287 +
legacy-tests/build/test/1/dgui_quickstart.html | 48 +
.../build/test/1/dgui_quickstart_basics.html | 135 +
.../build/test/1/dgui_quickstart_datamodel.html | 185 +
.../build/test/1/dgui_quickstart_template.html | 429 +
legacy-tests/build/test/1/dgui_template.html | 51 +
.../build/test/1/dgui_template_directives.html | 127 +
legacy-tests/build/test/1/dgui_template_exp.html | 1944 ++
.../test/1/dgui_template_overallstructure.html | 122 +
.../build/test/1/dgui_template_valueinsertion.html | 257 +
.../build/test/1/docgen-resources}/fonts/NOTICE | 0
.../test/1/docgen-resources}/fonts/icomoon.eot | Bin
.../test/1/docgen-resources}/fonts/icomoon.svg | 0
.../test/1/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/1/docgen-resources}/fonts/icomoon.woff | Bin
.../test/1/docgen-resources}/img/patterned-bg.png | Bin
.../build/test/1/docgen-resources}/img/xxe.png | Bin
legacy-tests/build/test/1/eclipse-toc.xml | 610 +
.../build}/test/1/figures/model2sketch.png | Bin
.../build}/test/1/figures/overview.png | Bin
.../build}/test/1/figures/tree.png | Bin
legacy-tests/build/test/1/gloss.html | 707 +
legacy-tests/build/test/1/index.html | 46 +
{src/test/9 => legacy-tests/build/test/1}/logo.png | Bin
legacy-tests/build/test/1/pgui.html | 45 +
legacy-tests/build/test/1/pgui_config.html | 46 +
legacy-tests/build/test/1/pgui_config_basics.html | 61 +
.../build/test/1/pgui_config_errorhandling.html | 364 +
.../build/test/1/pgui_config_settings.html | 301 +
.../build/test/1/pgui_config_sharedvariables.html | 134 +
.../build/test/1/pgui_config_templateloading.html | 316 +
legacy-tests/build/test/1/pgui_datamodel.html | 46 +
.../build/test/1/pgui_datamodel_basics.html | 96 +
.../build/test/1/pgui_datamodel_directive.html | 402 +
.../build/test/1/pgui_datamodel_method.html | 81 +
legacy-tests/build/test/1/pgui_datamodel_node.html | 114 +
.../build/test/1/pgui_datamodel_objectWrapper.html | 231 +
.../build/test/1/pgui_datamodel_parent.html | 120 +
.../build/test/1/pgui_datamodel_scalar.html | 144 +
legacy-tests/build/test/1/pgui_misc.html | 46 +
legacy-tests/build/test/1/pgui_misc_ant.html | 102 +
.../build/test/1/pgui_misc_beanwrapper.html | 640 +
legacy-tests/build/test/1/pgui_misc_charset.html | 169 +
.../build/test/1/pgui_misc_jythonwrapper.html | 124 +
legacy-tests/build/test/1/pgui_misc_logging.html | 128 +
.../build/test/1/pgui_misc_multithreading.html | 64 +
legacy-tests/build/test/1/pgui_misc_secureenv.html | 76 +
legacy-tests/build/test/1/pgui_misc_servlet.html | 549 +
legacy-tests/build/test/1/pgui_misc_var.html | 104 +
.../build/test/1/pgui_misc_xml_legacy.html | 496 +
legacy-tests/build/test/1/pgui_quickstart.html | 46 +
legacy-tests/build/test/1/pgui_quickstart_all.html | 89 +
.../1/pgui_quickstart_createconfiguration.html | 61 +
.../test/1/pgui_quickstart_createdatamodel.html | 104 +
.../build/test/1/pgui_quickstart_gettemplate.html | 60 +
.../build/test/1/pgui_quickstart_merge.html | 61 +
legacy-tests/build/test/1/preface.html | 206 +
{src => legacy-tests/build}/test/1/preface.xml | 0
legacy-tests/build/test/1/ref.html | 45 +
legacy-tests/build/test/1/ref_builtins.html | 328 +
.../build/test/1/ref_builtins_boolean.html | 88 +
legacy-tests/build/test/1/ref_builtins_date.html | 283 +
legacy-tests/build/test/1/ref_builtins_expert.html | 395 +
legacy-tests/build/test/1/ref_builtins_hash.html | 95 +
legacy-tests/build/test/1/ref_builtins_node.html | 204 +
legacy-tests/build/test/1/ref_builtins_number.html | 335 +
.../build/test/1/ref_builtins_sequence.html | 478 +
legacy-tests/build/test/1/ref_builtins_string.html | 1410 +
legacy-tests/build/test/1/ref_depr_builtin.html | 96 +
legacy-tests/build/test/1/ref_depr_directive.html | 82 +
.../test/1/ref_depr_numerical_interpolation.html | 126 +
legacy-tests/build/test/1/ref_depr_oldmacro.html | 189 +
legacy-tests/build/test/1/ref_depr_oldsyntax.html | 121 +
legacy-tests/build/test/1/ref_depr_transform.html | 154 +
legacy-tests/build/test/1/ref_deprecated.html | 45 +
.../build/test/1/ref_directive_assign.html | 189 +
.../build/test/1/ref_directive_attempt.html | 196 +
.../build/test/1/ref_directive_compress.html | 98 +
.../build/test/1/ref_directive_escape.html | 208 +
legacy-tests/build/test/1/ref_directive_flush.html | 83 +
legacy-tests/build/test/1/ref_directive_ftl.html | 230 +
.../build/test/1/ref_directive_function.html | 164 +
.../build/test/1/ref_directive_global.html | 119 +
legacy-tests/build/test/1/ref_directive_if.html | 178 +
.../build/test/1/ref_directive_import.html | 141 +
.../build/test/1/ref_directive_include.html | 419 +
legacy-tests/build/test/1/ref_directive_list.html | 180 +
legacy-tests/build/test/1/ref_directive_local.html | 97 +
legacy-tests/build/test/1/ref_directive_macro.html | 384 +
.../build/test/1/ref_directive_noparse.html | 96 +
legacy-tests/build/test/1/ref_directive_nt.html | 71 +
.../build/test/1/ref_directive_setting.html | 194 +
legacy-tests/build/test/1/ref_directive_stop.html | 83 +
.../build/test/1/ref_directive_switch.html | 150 +
legacy-tests/build/test/1/ref_directive_t.html | 143 +
.../build/test/1/ref_directive_userDefined.html | 288 +
legacy-tests/build/test/1/ref_directive_visit.html | 375 +
legacy-tests/build/test/1/ref_directives.html | 191 +
legacy-tests/build/test/1/ref_reservednames.html | 85 +
legacy-tests/build/test/1/ref_specvar.html | 166 +
legacy-tests/build/test/1/sitemap.xml | 459 +
legacy-tests/build/test/1/toc.js | 3889 +++
legacy-tests/build/test/1/versions_2_0.html | 138 +
legacy-tests/build/test/1/versions_2_01.html | 50 +
legacy-tests/build/test/1/versions_2_0RC1.html | 259 +
legacy-tests/build/test/1/versions_2_0RC2.html | 210 +
legacy-tests/build/test/1/versions_2_0RC3.html | 129 +
legacy-tests/build/test/1/versions_2_1.html | 529 +
legacy-tests/build/test/1/versions_2_1_1.html | 115 +
legacy-tests/build/test/1/versions_2_1_2.html | 121 +
legacy-tests/build/test/1/versions_2_1_3.html | 85 +
legacy-tests/build/test/1/versions_2_1_4.html | 64 +
legacy-tests/build/test/1/versions_2_1_5.html | 79 +
legacy-tests/build/test/1/versions_2_2.html | 1097 +
legacy-tests/build/test/1/versions_2_2_1.html | 117 +
legacy-tests/build/test/1/versions_2_2_2.html | 65 +
legacy-tests/build/test/1/versions_2_2_3.html | 97 +
legacy-tests/build/test/1/versions_2_2_4.html | 94 +
legacy-tests/build/test/1/versions_2_2_5.html | 59 +
legacy-tests/build/test/1/versions_2_2_6.html | 135 +
legacy-tests/build/test/1/versions_2_2_7.html | 60 +
legacy-tests/build/test/1/versions_2_2_8.html | 103 +
legacy-tests/build/test/1/versions_2_3.html | 1620 +
legacy-tests/build/test/1/versions_2_3_1.html | 343 +
legacy-tests/build/test/1/versions_2_3_10.html | 107 +
legacy-tests/build/test/1/versions_2_3_11.html | 217 +
legacy-tests/build/test/1/versions_2_3_12.html | 79 +
legacy-tests/build/test/1/versions_2_3_13.html | 116 +
legacy-tests/build/test/1/versions_2_3_14.html | 127 +
legacy-tests/build/test/1/versions_2_3_15.html | 115 +
legacy-tests/build/test/1/versions_2_3_16.html | 43 +
legacy-tests/build/test/1/versions_2_3_2.html | 67 +
legacy-tests/build/test/1/versions_2_3_3.html | 214 +
legacy-tests/build/test/1/versions_2_3_4.html | 112 +
legacy-tests/build/test/1/versions_2_3_5.html | 153 +
legacy-tests/build/test/1/versions_2_3_6.html | 59 +
legacy-tests/build/test/1/versions_2_3_7.html | 160 +
legacy-tests/build/test/1/versions_2_3_7rc1.html | 120 +
legacy-tests/build/test/1/versions_2_3_8.html | 89 +
legacy-tests/build/test/1/versions_2_3_9.html | 110 +
legacy-tests/build/test/1/xgui.html | 45 +
legacy-tests/build/test/1/xgui_declarative.html | 45 +
.../build/test/1/xgui_declarative_basics.html | 189 +
.../build/test/1/xgui_declarative_details.html | 211 +
legacy-tests/build/test/1/xgui_expose.html | 45 +
legacy-tests/build/test/1/xgui_expose_dom.html | 164 +
legacy-tests/build/test/1/xgui_expose_put.html | 74 +
legacy-tests/build/test/1/xgui_imperative.html | 45 +
.../build/test/1/xgui_imperative_formal.html | 500 +
.../build/test/1/xgui_imperative_learn.html | 649 +
legacy-tests/build/test/1/xgui_preface.html | 65 +
legacy-tests/build/test/2/autoid_2.html | 45 +
legacy-tests/build/test/2/autoid_3.html | 82 +
legacy-tests/build/test/2/autoid_4.html | 78 +
legacy-tests/build/test/2/autoid_5.html | 45 +
legacy-tests/build/test/2/autoid_6.html | 44 +
legacy-tests/build/test/2/autoid_7.html | 45 +
legacy-tests/build/test/2/autoid_8.html | 52 +
.../build/test/2/docgen-resources}/fonts/NOTICE | 0
.../test/2/docgen-resources}/fonts/icomoon.eot | Bin
.../test/2/docgen-resources}/fonts/icomoon.svg | 0
.../test/2/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/2/docgen-resources}/fonts/icomoon.woff | Bin
.../test/2/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/2/eclipse-toc.xml | 50 +
legacy-tests/build/test/2/index.html | 45 +
{src/test/8 => legacy-tests/build/test/2}/logo.png | Bin
legacy-tests/build/test/2/prg.html | 149 +
legacy-tests/build/test/2/sitemap.xml | 39 +
legacy-tests/build/test/2/tables.html | 261 +
{src => legacy-tests/build}/test/2/test.gif | Bin
legacy-tests/build/test/2/toc.js | 94 +
legacy-tests/build/test/2/xrefs.html | 55 +
legacy-tests/build/test/2/yet_another_section.html | 43 +
.../build/test/3/docgen-resources}/fonts/NOTICE | 0
.../test/3/docgen-resources}/fonts/icomoon.eot | Bin
.../test/3/docgen-resources}/fonts/icomoon.svg | 0
.../test/3/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/3/docgen-resources}/fonts/icomoon.woff | Bin
.../test/3/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/3/eclipse-toc.xml | 6 +
legacy-tests/build/test/3/index.html | 628 +
{src/test/7 => legacy-tests/build/test/3}/logo.png | Bin
legacy-tests/build/test/3/sitemap.xml | 6 +
{src/test/2 => legacy-tests/build/test/3}/test.gif | Bin
legacy-tests/build/test/3/toc.js | 94 +
legacy-tests/build/test/4/alphaidx.html | 1278 +
legacy-tests/build/test/4/app.html | 42 +
legacy-tests/build/test/4/app_build.html | 55 +
legacy-tests/build/test/4/app_faq.html | 1683 ++
legacy-tests/build/test/4/app_install.html | 96 +
legacy-tests/build/test/4/app_license.html | 89 +
legacy-tests/build/test/4/app_versions.html | 42 +
{src/test/1 => legacy-tests/build/test/4}/bat.jpg | Bin
legacy-tests/build/test/4/detailed-toc.html | 66 +
legacy-tests/build/test/4/dgui.html | 42 +
legacy-tests/build/test/4/dgui_datamodel.html | 42 +
.../build/test/4/dgui_datamodel_basics.html | 218 +
.../build/test/4/dgui_datamodel_types.html | 455 +
legacy-tests/build/test/4/dgui_misc.html | 42 +
.../build/test/4/dgui_misc_alternativesyntax.html | 107 +
legacy-tests/build/test/4/dgui_misc_namespace.html | 337 +
.../build/test/4/dgui_misc_userdefdir.html | 527 +
legacy-tests/build/test/4/dgui_misc_var.html | 158 +
.../build/test/4/dgui_misc_whitespace.html | 284 +
legacy-tests/build/test/4/dgui_quickstart.html | 45 +
.../build/test/4/dgui_quickstart_basics.html | 132 +
.../build/test/4/dgui_quickstart_datamodel.html | 182 +
.../build/test/4/dgui_quickstart_template.html | 426 +
legacy-tests/build/test/4/dgui_template.html | 48 +
.../build/test/4/dgui_template_directives.html | 124 +
legacy-tests/build/test/4/dgui_template_exp.html | 1941 ++
.../test/4/dgui_template_overallstructure.html | 119 +
.../build/test/4/dgui_template_valueinsertion.html | 256 +
.../build/test/4/docgen-resources}/fonts/NOTICE | 0
.../test/4/docgen-resources}/fonts/icomoon.eot | Bin
.../test/4/docgen-resources}/fonts/icomoon.svg | 0
.../test/4/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/4/docgen-resources}/fonts/icomoon.woff | Bin
.../test/4/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/4/eclipse-toc.xml | 610 +
.../build/test/4}/figures/model2sketch.png | Bin
.../build/test/4}/figures/overview.png | Bin
.../build/test/4}/figures/tree.png | Bin
legacy-tests/build/test/4/gloss.html | 704 +
legacy-tests/build/test/4/index.html | 43 +
{src/test/6 => legacy-tests/build/test/4}/logo.png | Bin
legacy-tests/build/test/4/pgui.html | 42 +
legacy-tests/build/test/4/pgui_config.html | 43 +
legacy-tests/build/test/4/pgui_config_basics.html | 58 +
.../build/test/4/pgui_config_errorhandling.html | 361 +
.../build/test/4/pgui_config_settings.html | 298 +
.../build/test/4/pgui_config_sharedvariables.html | 131 +
.../build/test/4/pgui_config_templateloading.html | 313 +
legacy-tests/build/test/4/pgui_datamodel.html | 43 +
.../build/test/4/pgui_datamodel_basics.html | 93 +
.../build/test/4/pgui_datamodel_directive.html | 399 +
.../build/test/4/pgui_datamodel_method.html | 78 +
legacy-tests/build/test/4/pgui_datamodel_node.html | 111 +
.../build/test/4/pgui_datamodel_objectWrapper.html | 228 +
.../build/test/4/pgui_datamodel_parent.html | 117 +
.../build/test/4/pgui_datamodel_scalar.html | 141 +
legacy-tests/build/test/4/pgui_misc.html | 43 +
legacy-tests/build/test/4/pgui_misc_ant.html | 99 +
.../build/test/4/pgui_misc_beanwrapper.html | 637 +
legacy-tests/build/test/4/pgui_misc_charset.html | 166 +
.../build/test/4/pgui_misc_jythonwrapper.html | 121 +
legacy-tests/build/test/4/pgui_misc_logging.html | 125 +
.../build/test/4/pgui_misc_multithreading.html | 61 +
legacy-tests/build/test/4/pgui_misc_secureenv.html | 73 +
legacy-tests/build/test/4/pgui_misc_servlet.html | 546 +
legacy-tests/build/test/4/pgui_misc_var.html | 101 +
.../build/test/4/pgui_misc_xml_legacy.html | 493 +
legacy-tests/build/test/4/pgui_quickstart.html | 43 +
legacy-tests/build/test/4/pgui_quickstart_all.html | 86 +
.../4/pgui_quickstart_createconfiguration.html | 58 +
.../test/4/pgui_quickstart_createdatamodel.html | 101 +
.../build/test/4/pgui_quickstart_gettemplate.html | 57 +
.../build/test/4/pgui_quickstart_merge.html | 58 +
legacy-tests/build/test/4/preface.html | 203 +
.../1 => legacy-tests/build/test/4}/preface.xml | 0
legacy-tests/build/test/4/ref.html | 42 +
legacy-tests/build/test/4/ref_builtins.html | 325 +
.../build/test/4/ref_builtins_boolean.html | 85 +
legacy-tests/build/test/4/ref_builtins_date.html | 280 +
legacy-tests/build/test/4/ref_builtins_expert.html | 392 +
legacy-tests/build/test/4/ref_builtins_hash.html | 92 +
legacy-tests/build/test/4/ref_builtins_node.html | 201 +
legacy-tests/build/test/4/ref_builtins_number.html | 332 +
.../build/test/4/ref_builtins_sequence.html | 475 +
legacy-tests/build/test/4/ref_builtins_string.html | 1407 +
legacy-tests/build/test/4/ref_depr_builtin.html | 93 +
legacy-tests/build/test/4/ref_depr_directive.html | 79 +
.../test/4/ref_depr_numerical_interpolation.html | 123 +
legacy-tests/build/test/4/ref_depr_oldmacro.html | 186 +
legacy-tests/build/test/4/ref_depr_oldsyntax.html | 118 +
legacy-tests/build/test/4/ref_depr_transform.html | 151 +
legacy-tests/build/test/4/ref_deprecated.html | 42 +
.../build/test/4/ref_directive_assign.html | 186 +
.../build/test/4/ref_directive_attempt.html | 193 +
.../build/test/4/ref_directive_compress.html | 95 +
.../build/test/4/ref_directive_escape.html | 205 +
legacy-tests/build/test/4/ref_directive_flush.html | 80 +
legacy-tests/build/test/4/ref_directive_ftl.html | 227 +
.../build/test/4/ref_directive_function.html | 161 +
.../build/test/4/ref_directive_global.html | 116 +
legacy-tests/build/test/4/ref_directive_if.html | 175 +
.../build/test/4/ref_directive_import.html | 138 +
.../build/test/4/ref_directive_include.html | 416 +
legacy-tests/build/test/4/ref_directive_list.html | 177 +
legacy-tests/build/test/4/ref_directive_local.html | 94 +
legacy-tests/build/test/4/ref_directive_macro.html | 381 +
.../build/test/4/ref_directive_noparse.html | 93 +
legacy-tests/build/test/4/ref_directive_nt.html | 68 +
.../build/test/4/ref_directive_setting.html | 191 +
legacy-tests/build/test/4/ref_directive_stop.html | 80 +
.../build/test/4/ref_directive_switch.html | 147 +
legacy-tests/build/test/4/ref_directive_t.html | 140 +
.../build/test/4/ref_directive_userDefined.html | 285 +
legacy-tests/build/test/4/ref_directive_visit.html | 372 +
legacy-tests/build/test/4/ref_directives.html | 188 +
legacy-tests/build/test/4/ref_reservednames.html | 82 +
legacy-tests/build/test/4/ref_specvar.html | 163 +
legacy-tests/build/test/4/sitemap.xml | 459 +
legacy-tests/build/test/4/toc.js | 3920 +++
legacy-tests/build/test/4/versions_2_0.html | 135 +
legacy-tests/build/test/4/versions_2_01.html | 47 +
legacy-tests/build/test/4/versions_2_0RC1.html | 256 +
legacy-tests/build/test/4/versions_2_0RC2.html | 207 +
legacy-tests/build/test/4/versions_2_0RC3.html | 126 +
legacy-tests/build/test/4/versions_2_1.html | 526 +
legacy-tests/build/test/4/versions_2_1_1.html | 112 +
legacy-tests/build/test/4/versions_2_1_2.html | 118 +
legacy-tests/build/test/4/versions_2_1_3.html | 82 +
legacy-tests/build/test/4/versions_2_1_4.html | 61 +
legacy-tests/build/test/4/versions_2_1_5.html | 76 +
legacy-tests/build/test/4/versions_2_2.html | 1094 +
legacy-tests/build/test/4/versions_2_2_1.html | 114 +
legacy-tests/build/test/4/versions_2_2_2.html | 62 +
legacy-tests/build/test/4/versions_2_2_3.html | 94 +
legacy-tests/build/test/4/versions_2_2_4.html | 91 +
legacy-tests/build/test/4/versions_2_2_5.html | 56 +
legacy-tests/build/test/4/versions_2_2_6.html | 132 +
legacy-tests/build/test/4/versions_2_2_7.html | 57 +
legacy-tests/build/test/4/versions_2_2_8.html | 100 +
legacy-tests/build/test/4/versions_2_3.html | 1617 +
legacy-tests/build/test/4/versions_2_3_1.html | 340 +
legacy-tests/build/test/4/versions_2_3_10.html | 104 +
legacy-tests/build/test/4/versions_2_3_11.html | 214 +
legacy-tests/build/test/4/versions_2_3_12.html | 76 +
legacy-tests/build/test/4/versions_2_3_13.html | 113 +
legacy-tests/build/test/4/versions_2_3_14.html | 124 +
legacy-tests/build/test/4/versions_2_3_15.html | 112 +
legacy-tests/build/test/4/versions_2_3_16.html | 40 +
legacy-tests/build/test/4/versions_2_3_2.html | 64 +
legacy-tests/build/test/4/versions_2_3_3.html | 211 +
legacy-tests/build/test/4/versions_2_3_4.html | 109 +
legacy-tests/build/test/4/versions_2_3_5.html | 150 +
legacy-tests/build/test/4/versions_2_3_6.html | 56 +
legacy-tests/build/test/4/versions_2_3_7.html | 157 +
legacy-tests/build/test/4/versions_2_3_7rc1.html | 117 +
legacy-tests/build/test/4/versions_2_3_8.html | 86 +
legacy-tests/build/test/4/versions_2_3_9.html | 107 +
legacy-tests/build/test/4/xgui.html | 42 +
legacy-tests/build/test/4/xgui_declarative.html | 42 +
.../build/test/4/xgui_declarative_basics.html | 186 +
.../build/test/4/xgui_declarative_details.html | 208 +
legacy-tests/build/test/4/xgui_expose.html | 42 +
legacy-tests/build/test/4/xgui_expose_dom.html | 161 +
legacy-tests/build/test/4/xgui_expose_put.html | 71 +
legacy-tests/build/test/4/xgui_imperative.html | 42 +
.../build/test/4/xgui_imperative_formal.html | 497 +
.../build/test/4/xgui_imperative_learn.html | 646 +
legacy-tests/build/test/4/xgui_preface.html | 62 +
.../build/test/5/docgen-resources}/fonts/NOTICE | 0
.../test/5/docgen-resources}/fonts/icomoon.eot | Bin
.../test/5/docgen-resources}/fonts/icomoon.svg | 0
.../test/5/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/5/docgen-resources}/fonts/icomoon.woff | Bin
.../test/5/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/5/eclipse-toc.xml | 6 +
legacy-tests/build/test/5/index.html | 492 +
{src => legacy-tests/build}/test/5/logo.png | Bin
legacy-tests/build/test/5/sitemap.xml | 6 +
legacy-tests/build/test/5/toc.js | 243 +
.../build/test/6/docgen-resources}/fonts/NOTICE | 0
.../test/6/docgen-resources}/fonts/icomoon.eot | Bin
.../test/6/docgen-resources}/fonts/icomoon.svg | 0
.../test/6/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/6/docgen-resources}/fonts/icomoon.woff | Bin
.../test/6/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/6/eclipse-toc.xml | 6 +
legacy-tests/build/test/6/index.html | 156 +
{src/test/4 => legacy-tests/build/test/6}/logo.png | Bin
legacy-tests/build/test/6/sitemap.xml | 6 +
legacy-tests/build/test/6/toc.js | 85 +
legacy-tests/build/test/7/autoid_2.html | 43 +
legacy-tests/build/test/7/autoid_3.html | 101 +
legacy-tests/build/test/7/autoid_9.html | 63 +
legacy-tests/build/test/7/detailed-toc.html | 44 +
.../build/test/7/docgen-resources}/fonts/NOTICE | 0
.../test/7/docgen-resources}/fonts/icomoon.eot | Bin
.../test/7/docgen-resources}/fonts/icomoon.svg | 0
.../test/7/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/7/docgen-resources}/fonts/icomoon.woff | Bin
.../test/7/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/7/eclipse-toc.xml | 18 +
legacy-tests/build/test/7/index.html | 45 +
{src/test/3 => legacy-tests/build/test/7}/logo.png | Bin
legacy-tests/build/test/7/sitemap.xml | 15 +
legacy-tests/build/test/7/toc.js | 85 +
.../build/test/8/docgen-resources}/fonts/NOTICE | 0
.../test/8/docgen-resources}/fonts/icomoon.eot | Bin
.../test/8/docgen-resources}/fonts/icomoon.svg | 0
.../test/8/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/8/docgen-resources}/fonts/icomoon.woff | Bin
.../test/8/docgen-resources}/img/patterned-bg.png | Bin
legacy-tests/build/test/8/eclipse-toc.xml | 6 +
legacy-tests/build/test/8/index.html | 154 +
{src/test/2 => legacy-tests/build/test/8}/logo.png | Bin
legacy-tests/build/test/8/sitemap.xml | 6 +
legacy-tests/build/test/8/toc.js | 9 +
{src/test/1 => legacy-tests/build/test/9}/bat.jpg | Bin
.../build/test/9/docgen-resources}/fonts/NOTICE | 0
.../test/9/docgen-resources}/fonts/icomoon.eot | Bin
.../test/9/docgen-resources}/fonts/icomoon.svg | 0
.../test/9/docgen-resources}/fonts/icomoon.ttf | Bin
.../test/9/docgen-resources}/fonts/icomoon.woff | Bin
.../test/9/docgen-resources}/img/patterned-bg.png | Bin
.../build/test/9/docgen-resources}/img/xxe.png | Bin
.../build/test/9}/figures/model2sketch.png | Bin
.../build/test/9}/figures/overview.png | Bin
.../build/test/9}/figures/tree.png | Bin
legacy-tests/build/test/9/index.html | 30132 +++++++++++++++++++
{src/test/1 => legacy-tests/build/test/9}/logo.png | Bin
.../1 => legacy-tests/build/test/9}/preface.xml | 0
legacy-tests/build/test/9/sitemap.xml | 6 +
legacy-tests/build/test/9/toc.js | 3889 +++
{src/test => legacy-tests/srcdirs}/1/bat.jpg | Bin
{src/test => legacy-tests/srcdirs}/1/book.xml | 0
.../test => legacy-tests/srcdirs}/1/docgen-foo.txt | 0
.../srcdirs}/1/docgen-templates/customizations.ftl | 0
{src/test => legacy-tests/srcdirs}/1/docgen.cjson | 1 +
{src/test => legacy-tests/srcdirs}/1/docgen.txt | 0
.../srcdirs}/1/figures/model2sketch.png | Bin
.../srcdirs}/1/figures/overview.png | Bin
.../srcdirs}/1/figures/tree.png | Bin
{src/test/9 => legacy-tests/srcdirs/1}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/1/preface.xml | 0
{src/test => legacy-tests/srcdirs}/2/book.xml | 0
{src/test => legacy-tests/srcdirs}/2/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/2}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/2/test.gif | Bin
{src/test => legacy-tests/srcdirs}/3/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/3}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/4/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/4}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/5/book.xml | 0
{src/test => legacy-tests/srcdirs}/5/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/5}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/6/article.xml | 0
{src/test => legacy-tests/srcdirs}/6/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/6}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/7/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/7}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/8/docgen.cjson | 1 +
{src/test/9 => legacy-tests/srcdirs/8}/logo.png | Bin
{src/test => legacy-tests/srcdirs}/9/docgen.cjson | 1 +
{src/test => legacy-tests/srcdirs}/9/logo.png | Bin
package-lock.json | 4387 +--
pom.xml | 123 +-
rat-excludes | 36 +-
.../org/freemarker/docgen/version.properties | 20 -
.../docbook-for-docgen/docbook-for-docgen.css | 0
.../docbook-for-docgen/docbook-for-docgen.xxe | 0
{src/xxe-addon => xxe-addon}/howto.txt | 0
559 files changed, 114821 insertions(+), 4614 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6b5be71..08f0117 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@
/out/
/bin/
/target/
+/*/target/
.classpath
.project
diff --git a/README.md b/README.md
index 2aa762f..d72a83e 100644
--- a/README.md
+++ b/README.md
@@ -12,12 +12,11 @@ it tries to be reusable in other projects as well.
Before building for the first time:
* JDK 8 must be used (tried with 1.8.0_212)
-* Apache Maven must be installed (tried with 3.6.1), and use JDK 8 for building.
+* Apache Maven must be installed (tried with 3.6.1)
* [Node.js](https://nodejs.org/) must be installed (tried with v10.16.2).
-* Create a `build.properties` file based on `build.properties.sample`
-* Issue `npm install` from the project directory to install Node.js
- dependencies. This need to be repeated if you add new dependencies
- to `gulpfile.js`.
+* Go to `freemarker-docgen-core`, and issue `npm install` there to install
+ Node.js dependencies. Repeat this step if you add new dependencies to
+ `gulpfile.js`.
Possible node.js related problems and solutions:
* "Error: ENOENT, stat <someDirectoryHere>": create that directory manually,
@@ -29,19 +28,19 @@ Possible node.js related problems and solutions:
modules, or anything strange, delete the "node_modules" directory, and
issue `npm install` to recreate it.
-To build Docgen:
+To build Docgen (again, do the npm npm installation first!):
```sh
mvn install
```
For some examples see:
-* `src/test` and `test.xml` in this project
+* `legacy-tests`
* `src/manual` in [the `freemarker` project](https://git-wip-us.apache.org/repos/asf/incubator-freemarker.git)
* `src/main/docgen` the [`site` project](https://git-wip-us.apache.org/repos/asf/incubator-freemarker-site.git)
For editing DocBook, we are using [XXE](http://www.xmlmind.com/xmleditor/)
-with the `src/xxe-addon` installed.
+with the `xxe-addon` installed.
### Try your modifications
@@ -66,7 +65,7 @@ The generated output is in `target\resources-gulp`.
## Publishing a new Docgen version
-TODO
+TODO Standard ASF release procedure. Binary release to Maven Central.
## Icon Font Attribution
diff --git a/freemarker-docgen-ant/pom.xml b/freemarker-docgen-ant/pom.xml
new file mode 100644
index 0000000..9c316fd
--- /dev/null
+++ b/freemarker-docgen-ant/pom.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen</artifactId>
+ <version>0.0.1</version>
+ </parent>
+
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-ant</artifactId>
+ <name>Apache FreeMarker Docgen - Ant</name>
+ <description>Docgen Ant task</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ant</groupId>
+ <artifactId>ant</artifactId>
+ <version>1.9.3</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
+ <excludeScope>provided</excludeScope>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/main/java/org/freemarker/docgen/TransformAntTask.java b/freemarker-docgen-ant/src/main/java/org/freemarker/docgen/TransformAntTask.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/TransformAntTask.java
rename to freemarker-docgen-ant/src/main/java/org/freemarker/docgen/TransformAntTask.java
diff --git a/src/main/resources/org/freemarker/docgen/antlib.properties b/freemarker-docgen-ant/src/main/resources/org/freemarker/docgen/antlib.properties
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/antlib.properties
rename to freemarker-docgen-ant/src/main/resources/org/freemarker/docgen/antlib.properties
diff --git a/freemarker-docgen-cli/pom.xml b/freemarker-docgen-cli/pom.xml
new file mode 100644
index 0000000..3db42bd
--- /dev/null
+++ b/freemarker-docgen-cli/pom.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen</artifactId>
+ <version>0.0.1</version>
+ </parent>
+
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-cli</artifactId>
+ <name>Apache FreeMarker Docgen - CLI</name>
+ <description>Docgen command line interface</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <mainClass>org.freemarker.docgen.TransformCommandLine</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>copy-dependencies</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}/dependencies</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/main/java/org/freemarker/docgen/TransformCommandLine.java b/freemarker-docgen-cli/src/main/java/org/freemarker/docgen/TransformCommandLine.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/TransformCommandLine.java
rename to freemarker-docgen-cli/src/main/java/org/freemarker/docgen/TransformCommandLine.java
diff --git a/gulp-output-copyright-header.txt b/freemarker-docgen-core/gulp-output-copyright-header.txt
similarity index 100%
rename from gulp-output-copyright-header.txt
rename to freemarker-docgen-core/gulp-output-copyright-header.txt
diff --git a/gulpfile.js b/freemarker-docgen-core/gulpfile.js
similarity index 100%
rename from gulpfile.js
rename to freemarker-docgen-core/gulpfile.js
diff --git a/package-lock.json b/freemarker-docgen-core/package-lock.json
similarity index 100%
copy from package-lock.json
copy to freemarker-docgen-core/package-lock.json
diff --git a/package.json b/freemarker-docgen-core/package.json
similarity index 100%
rename from package.json
rename to freemarker-docgen-core/package.json
diff --git a/pom.xml b/freemarker-docgen-core/pom.xml
similarity index 56%
copy from pom.xml
copy to freemarker-docgen-core/pom.xml
index 27b2753..e2cb3b0 100644
--- a/pom.xml
+++ b/freemarker-docgen-core/pom.xml
@@ -21,24 +21,13 @@
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>org.apache</groupId>
- <artifactId>apache</artifactId>
- <version>23</version>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen</artifactId>
+ <version>0.0.1</version>
</parent>
- <groupId>org.apache.freemarker.docgen</groupId>
- <artifactId>freemarker-docgen</artifactId>
- <version>0.0.1</version>
- <name>Apache FreeMarker Docgen</name>
- <description>Internally used tool to generate HTML from an XDocBook document.</description>
- <packaging>maven-plugin</packaging>
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <maven.compiler.source>1.8</maven.compiler.source>
- <maven.compiler.target>1.8</maven.compiler.target>
- <dependency.maven.version>3.5.2</dependency.maven.version>
- </properties>
+ <artifactId>freemarker-docgen-core</artifactId>
+ <name>Apache FreeMarker Docgen - Core</name>
<dependencies>
<dependency>
@@ -73,33 +62,6 @@
</exclusion>
</exclusions>
</dependency>
- <dependency>
- <groupId>org.apache.ant</groupId>
- <artifactId>ant</artifactId>
- <version>1.9.3</version>
- <scope>provided</scope>
- </dependency>
-
- <!--
- <dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-core</artifactId>
- <version>${dependency.maven.version}</version>
- <scope>provided</scope>
- </dependency>
- -->
- <dependency>
- <groupId>org.apache.maven</groupId>
- <artifactId>maven-plugin-api</artifactId>
- <version>${dependency.maven.version}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.maven.plugin-tools</groupId>
- <artifactId>maven-plugin-annotations</artifactId>
- <version>${dependency.maven.version}</version>
- <scope>provided</scope>
- </dependency>
</dependencies>
<build>
@@ -134,33 +96,6 @@
</execution>
</executions>
</plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-jar-plugin</artifactId>
- <configuration>
- <archive>
- <manifest>
- <mainClass>org.freemarker.docgen.TransformCommandLine</mainClass>
- </manifest>
- </archive>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.rat</groupId>
- <artifactId>apache-rat-plugin</artifactId>
- <version>0.13</version>
- <executions>
- <execution>
- <phase>verify</phase>
- <goals>
- <goal>check</goal>
- </goals>
- </execution>
- </executions>
- <configuration>
- <excludesFile>rat-excludes</excludesFile>
- </configuration>
- </plugin>
</plugins>
</build>
</project>
diff --git a/src/main/java/org/freemarker/docgen/BugException.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/BugException.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/BugException.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/BugException.java
diff --git a/src/main/java/org/freemarker/docgen/CJSONInterpreter.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/CJSONInterpreter.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/CJSONInterpreter.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/CJSONInterpreter.java
diff --git a/src/main/java/org/freemarker/docgen/CollectingErrorHandler.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/CollectingErrorHandler.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/CollectingErrorHandler.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/CollectingErrorHandler.java
diff --git a/src/main/java/org/freemarker/docgen/CommandLineExitException.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/CommandLineExitException.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/CommandLineExitException.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/CommandLineExitException.java
diff --git a/src/main/java/org/freemarker/docgen/DocBook5Constants.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocBook5Constants.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/DocBook5Constants.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocBook5Constants.java
diff --git a/src/main/java/org/freemarker/docgen/DocgenException.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenException.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/DocgenException.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenException.java
diff --git a/src/main/java/org/freemarker/docgen/DocgenLogger.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenLogger.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/DocgenLogger.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenLogger.java
diff --git a/src/main/java/org/freemarker/docgen/DocgenRestrictionsValidator.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenRestrictionsValidator.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/DocgenRestrictionsValidator.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenRestrictionsValidator.java
diff --git a/src/main/java/org/freemarker/docgen/DocgenValidationOptions.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenValidationOptions.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/DocgenValidationOptions.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/DocgenValidationOptions.java
diff --git a/src/main/java/org/freemarker/docgen/FileUtil.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/FileUtil.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/FileUtil.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/FileUtil.java
diff --git a/src/main/java/org/freemarker/docgen/Logo.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/Logo.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/Logo.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/Logo.java
diff --git a/src/main/java/org/freemarker/docgen/MessageStreamActivityMonitor.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/MessageStreamActivityMonitor.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/MessageStreamActivityMonitor.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/MessageStreamActivityMonitor.java
diff --git a/src/main/java/org/freemarker/docgen/RelaxNGValidator.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/RelaxNGValidator.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/RelaxNGValidator.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/RelaxNGValidator.java
diff --git a/src/main/java/org/freemarker/docgen/TableSimplifier.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/TableSimplifier.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/TableSimplifier.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/TableSimplifier.java
diff --git a/src/main/java/org/freemarker/docgen/TextUtil.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/TextUtil.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/TextUtil.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/TextUtil.java
diff --git a/src/main/java/org/freemarker/docgen/Transform.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/Transform.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/Transform.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/Transform.java
diff --git a/src/main/java/org/freemarker/docgen/ValidatingDOMBuilder.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/ValidatingDOMBuilder.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/ValidatingDOMBuilder.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/ValidatingDOMBuilder.java
diff --git a/src/main/java/org/freemarker/docgen/ValidatingDOMBuilderWithLocations.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/ValidatingDOMBuilderWithLocations.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/ValidatingDOMBuilderWithLocations.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/ValidatingDOMBuilderWithLocations.java
diff --git a/src/main/java/org/freemarker/docgen/XMLUtil.java b/freemarker-docgen-core/src/main/java/org/freemarker/docgen/XMLUtil.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/XMLUtil.java
rename to freemarker-docgen-core/src/main/java/org/freemarker/docgen/XMLUtil.java
diff --git a/src/main/java/overview.html b/freemarker-docgen-core/src/main/java/overview.html
similarity index 100%
rename from src/main/java/overview.html
rename to freemarker-docgen-core/src/main/java/overview.html
diff --git a/src/main/resources-gulp/org/freemarker/docgen/js/make-toc.js b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/make-toc.js
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/js/make-toc.js
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/make-toc.js
diff --git a/src/main/resources-gulp/org/freemarker/docgen/js/page-menu.js b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/page-menu.js
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/js/page-menu.js
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/page-menu.js
diff --git a/src/main/resources-gulp/org/freemarker/docgen/js/search.js b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/search.js
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/js/search.js
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/search.js
diff --git a/src/main/resources-gulp/org/freemarker/docgen/js/use-strict.js b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/use-strict.js
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/js/use-strict.js
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/js/use-strict.js
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/base.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/base.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/base.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/base.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/bookmarks.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/bookmarks.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/bookmarks.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/bookmarks.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/breadcrumb.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/breadcrumb.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/breadcrumb.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/breadcrumb.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/callout.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/callout.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/callout.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/callout.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/code-block.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/code-block.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/code-block.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/code-block.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/logo.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/logo.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/logo.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/logo.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/marked-text.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/marked-text.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/marked-text.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/marked-text.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/page-menu.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/page-menu.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/page-menu.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/page-menu.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/pagers.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/pagers.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/pagers.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/pagers.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-form.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-form.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-form.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-form.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-results.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-results.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-results.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/search-results.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/secondary-tabs.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/secondary-tabs.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/secondary-tabs.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/secondary-tabs.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/social-icons.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/social-icons.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/social-icons.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/social-icons.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table-of-contents.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table-of-contents.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table-of-contents.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table-of-contents.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/table.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/tabs.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/tabs.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/components/tabs.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/components/tabs.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/icons.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/icons.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/icons.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/icons.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/content.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/content.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/content.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/content.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/footer.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/footer.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/footer.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/footer.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/header.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/header.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/header.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/layout/header.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/mixins.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/mixins.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/mixins.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/mixins.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/utilities.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/utilities.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/utilities.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/utilities.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/lib/variables.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/variables.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/lib/variables.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/lib/variables.less
diff --git a/src/main/resources-gulp/org/freemarker/docgen/less/styles.less b/freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/styles.less
similarity index 100%
rename from src/main/resources-gulp/org/freemarker/docgen/less/styles.less
rename to freemarker-docgen-core/src/main/resources-gulp/org/freemarker/docgen/less/styles.less
diff --git a/src/main/resources/org/freemarker/docgen/schema/docbook.rng b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/schema/docbook.rng
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/schema/docbook.rng
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/schema/docbook.rng
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/NOTICE b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/NOTICE
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/fonts/NOTICE
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/NOTICE
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.eot b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.eot
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.eot
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.eot
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.svg b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.svg
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.svg
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.svg
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.ttf b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.ttf
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.ttf
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.ttf
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.woff b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.woff
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.woff
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/icomoon.woff
diff --git a/src/main/resources/org/freemarker/docgen/statics/fonts/selection.json b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/selection.json
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/statics/fonts/selection.json
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/fonts/selection.json
diff --git a/src/main/resources/org/freemarker/docgen/statics/img/patterned-bg.png b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/patterned-bg.png
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/img/patterned-bg.png
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/patterned-bg.png
diff --git a/src/main/resources/org/freemarker/docgen/statics/img/xxe.gif b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/xxe.gif
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/statics/img/xxe.gif
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/xxe.gif
diff --git a/src/main/resources/org/freemarker/docgen/statics/img/xxe.png b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/xxe.png
similarity index 100%
copy from src/main/resources/org/freemarker/docgen/statics/img/xxe.png
copy to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/statics/img/xxe.png
diff --git a/src/main/resources/org/freemarker/docgen/templates/customizations.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/customizations.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/customizations.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/customizations.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/eclipse-toc.ftlx b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/eclipse-toc.ftlx
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/eclipse-toc.ftlx
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/eclipse-toc.ftlx
diff --git a/src/main/resources/org/freemarker/docgen/templates/footer.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/footer.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/footer.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/footer.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/google.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/google.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/google.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/google.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/header.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/header.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/header.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/header.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/navigation.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/navigation.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/navigation.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/navigation.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/node-handlers.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/node-handlers.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/node-handlers.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/node-handlers.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/page.ftlh b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/page.ftlh
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/page.ftlh
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/page.ftlh
diff --git a/src/main/resources/org/freemarker/docgen/templates/sitemap.ftlx b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/sitemap.ftlx
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/sitemap.ftlx
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/sitemap.ftlx
diff --git a/src/main/resources/org/freemarker/docgen/templates/toc-json.ftl b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/toc-json.ftl
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/toc-json.ftl
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/toc-json.ftl
diff --git a/src/main/resources/org/freemarker/docgen/templates/util.ftl b/freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/util.ftl
similarity index 100%
rename from src/main/resources/org/freemarker/docgen/templates/util.ftl
rename to freemarker-docgen-core/src/main/resources/org/freemarker/docgen/templates/util.ftl
diff --git a/freemarker-docgen-maven/pom.xml b/freemarker-docgen-maven/pom.xml
new file mode 100644
index 0000000..e1cb69e
--- /dev/null
+++ b/freemarker-docgen-maven/pom.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen</artifactId>
+ <version>0.0.1</version>
+ </parent>
+
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-maven</artifactId>
+ <name>Apache FreeMarker Docgen - Maven</name>
+ <description>Docgen Maven plugin</description>
+ <packaging>maven-plugin</packaging>
+
+ <properties>
+ <dependency.maven.version>3.5.2</dependency.maven.version>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.freemarker.docgen</groupId>
+ <artifactId>freemarker-docgen-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven</groupId>
+ <artifactId>maven-plugin-api</artifactId>
+ <version>${dependency.maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.maven.plugin-tools</groupId>
+ <artifactId>maven-plugin-annotations</artifactId>
+ <version>${dependency.maven.version}</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/src/main/java/org/freemarker/docgen/TransformMojo.java b/freemarker-docgen-maven/src/main/java/org/freemarker/docgen/TransformMojo.java
similarity index 100%
rename from src/main/java/org/freemarker/docgen/TransformMojo.java
rename to freemarker-docgen-maven/src/main/java/org/freemarker/docgen/TransformMojo.java
diff --git a/legacy-tests/README b/legacy-tests/README
new file mode 100644
index 0000000..9be33bb
--- /dev/null
+++ b/legacy-tests/README
@@ -0,0 +1,4 @@
+Moved old tests here. These doesn't run as part of the build, but are ran manually.
+
+First, build the parent project via `mvn package`
+Then try to run `ant` from this directory.
\ No newline at end of file
diff --git a/test.xml b/legacy-tests/build.xml
similarity index 74%
rename from test.xml
rename to legacy-tests/build.xml
index a16633a..0311c68 100644
--- a/test.xml
+++ b/legacy-tests/build.xml
@@ -25,9 +25,16 @@
-->
<project name="docgen-test" default="test" xmlns:docgen="http://freemarker.org/docgen">
+ <path id="docgenJars.path">
+ <fileset dir="..">
+ <include name="freemarker-docgen-ant/target/freemarker-docgen-ant-*.jar"/>
+ <include name="freemarker-docgen-ant/target/dependencies/*.jar"/>
+ </fileset>
+ </path>
+
<taskdef resource="org/freemarker/docgen/antlib.properties"
uri="http://freemarker.org/docgen"
- classpath="build/lib/docgen.jar"
+ classpathref="docgenJars.path"
/>
<target name="test">
@@ -37,54 +44,54 @@
</delete>
<docgen:transform
- srcdir="src/test/9" destdir="build/test/9"
+ srcdir="srcdirs/9" destdir="build/test/9"
offline="true"
/>
<docgen:transform
- srcdir="src/test/8" destdir="build/test/8"
+ srcdir="srcdirs/8" destdir="build/test/8"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/7" destdir="build/test/7"
+ srcdir="srcdirs/7" destdir="build/test/7"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/6" destdir="build/test/6"
+ srcdir="srcdirs/6" destdir="build/test/6"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/5" destdir="build/test/5"
+ srcdir="srcdirs/5" destdir="build/test/5"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/4" destdir="build/test/4"
+ srcdir="srcdirs/4" destdir="build/test/4"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/3" destdir="build/test/3"
+ srcdir="srcdirs/3" destdir="build/test/3"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/2" destdir="build/test/2"
+ srcdir="srcdirs/2" destdir="build/test/2"
offline="true"
generateEclipseToC="true"
/>
<docgen:transform
- srcdir="src/test/1" destdir="build/test/1"
+ srcdir="srcdirs/1" destdir="build/test/1"
offline="true"
generateEclipseToC="true"
/>
diff --git a/legacy-tests/build/test/1/alphaidx.html b/legacy-tests/build/test/1/alphaidx.html
new file mode 100644
index 0000000..3dfb1ea
--- /dev/null
+++ b/legacy-tests/build/test/1/alphaidx.html
@@ -0,0 +1,1281 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-index">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Alphabetical Index - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Alphabetical Index">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/alphaidx.html">
+<link rel="canonical" href="http://example.com/alphaidx.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Alphabetical Index"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="gloss.html"><span>Previous</span></a><span class="paging-arrow disabled next"><span>Next</span></span></div><div class="title-wrapper">
+<h1 class="content-header header-part" id="alphaidx" itemprop="headline">Alphabetical Index</h1>
+</div></div>
+ <p>
+<a href="#idx_x24">$</a> | <a href="#idx_x23">#</a> | <a href="#idx_x3C"><</a> | <a href="#idx_A">A</a> | <a href="#idx_B">B</a> | <a href="#idx_C">C</a> | <a href="#idx_D">D</a> | <a href="#idx_E">E</a> | <a href="#idx_F">F</a> | <a href="#idx_G">G</a> | <a href="#idx_H">H</a> | <a href="#idx_I">I</a> | <a href="#idx_J">J</a> | <a href="#idx_K">K</a> | <a href="#idx_L">L</a> | <a href="#idx_M">M</a> | <a [...]
+
+<div class="indexdiv">
+<a name="idx_x24"></a>
+<h2 class="indexLabel">$</h2>
+<dl>
+ <dt>
+ ${...}, <a href="dgui_template_valueinsertion.html">Interpolations</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_x23"></a>
+<h2 class="indexLabel">#</h2>
+<dl>
+ <dt>
+ #, <a href="dgui_template_overallstructure.html">Overall structure</a>,
+<a href="dgui_template_directives.html">Directives</a>
+ </dt>
+ <dt>
+ #{...}, <a href="ref_depr_numerical_interpolation.html">#{...}: Numerical interpolation</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_x3C"></a>
+<h2 class="indexLabel"><</h2>
+<dl>
+ <dt>
+ <#...>, <a href="dgui_template_directives.html">Directives</a>
+ </dt>
+ <dt>
+ <#--...-->, <a href="dgui_template_overallstructure.html">Overall structure</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_A"></a>
+<h2 class="indexLabel">A</h2>
+<dl>
+ <dt>
+ acquisition, <a href="ref_directive_include.html#ref_directive_include_acquisition">Using acquisition</a>
+ </dt>
+ <dt>
+ adding hashes, <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ adding sequences, <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ adding strings, <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a>
+ </dt>
+ <dt>
+ addition, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ alternative syntax, <a href="dgui_misc_alternativesyntax.html">Alternative (square bracket) syntax</a>
+ </dt>
+ <dt>
+ ancestors built-in, <a href="ref_builtins_node.html#ref_builtin_ancestors">ancestors</a>
+ </dt>
+ <dt>
+ and, <a href="dgui_template_exp.html#dgui_template_exp_logicalop">Logical operations</a>
+ </dt>
+ <dt>
+ ant task, <a href="pgui_misc_ant.html">Using FreeMarker with Ant</a>
+ </dt>
+ <dt>
+ arithmetic, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ assign directive, <a href="ref_directive_assign.html">assign</a>
+ </dt>
+ <dt>
+ attempt directive, <a href="ref_directive_attempt.html">attempt, recover</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_B"></a>
+<h2 class="indexLabel">B</h2>
+<dl>
+ <dt>
+ beans </dt>
+ <dd><dl>
+ <dt>wrapping, <a href="pgui_misc_beanwrapper.html">Bean wrapper</a></dt>
+ </dl></dd>
+ <dt>
+ boolean </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_boolean.html">Built-ins for booleans</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ <dt>literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_boolean">Booleans</a></dt>
+ <dt>operations, <a href="dgui_template_exp.html#dgui_template_exp_logicalop">Logical operations</a></dt>
+ <dt>printing, <a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">string (when used with a boolean value)</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ boolean_format, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ break directive, <a href="ref_directive_switch.html">switch, case, default, break</a>,
+<a href="ref_directive_list.html">list, break</a>
+ </dt>
+ <dt>
+ build, <a href="app_build.html">Building FreeMarker</a>
+ </dt>
+ <dt>
+ built-in, <a href="dgui_template_exp.html#dgui_template_exp_builtin">Built-ins</a>,
+<a href="ref_builtins.html">Built-in Reference</a>
+ </dt>
+ <dt>
+ byte built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_C"></a>
+<h2 class="indexLabel">C</h2>
+<dl>
+ <dt>
+ caching, <a href="pgui_config_templateloading.html#pgui_config_templateloading_caching">Template caching</a>
+ </dt>
+ <dt>
+ call a method, <a href="dgui_template_exp.html#dgui_template_exp_methodcall">Method call</a>
+ </dt>
+ <dt>
+ cap_first built-in, <a href="ref_builtins_string.html#ref_builtin_cap_first">cap_first</a>
+ </dt>
+ <dt>
+ capitalize built-in, <a href="ref_builtins_string.html#ref_builtin_capitalize">capitalize</a>
+ </dt>
+ <dt>
+ case directive, <a href="ref_directive_switch.html">switch, case, default, break</a>
+ </dt>
+ <dt>
+ ceiling built-in, <a href="ref_builtins_number.html#ref_builtin_rounding">round, floor, ceiling</a>
+ </dt>
+ <dt>
+ charAt, <a href="dgui_template_exp.html#dgui_template_exp_get_character">Getting a character</a>
+ </dt>
+ <dt>
+ charset, <a href="pgui_misc_charset.html">Charset issues</a>,
+<a href="ref_directive_ftl.html">ftl</a>
+ </dt>
+ <dt>
+ children built-in, <a href="ref_builtins_node.html#ref_builtin_children">children</a>
+ </dt>
+ <dt>
+ chop_linebreak built-in, <a href="ref_builtins_string.html#ref_builtin_chop_linebreak">chop_linebreak</a>
+ </dt>
+ <dt>
+ chunk built-in, <a href="ref_builtins_sequence.html#ref_builtin_chunk">chunk</a>
+ </dt>
+ <dt>
+ classic_compatible, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ collection </dt>
+ <dd><dl>
+ <dt>Java side, <a href="pgui_datamodel_parent.html#autoid_34">Containers</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_container">Containers</a></dt>
+ </dl></dd>
+ <dt>
+ columnar printing of sequences, <a href="ref_builtins_sequence.html#ref_builtin_chunk">chunk</a>
+ </dt>
+ <dt>
+ command-line, <a href="pgui_misc_ant.html">Using FreeMarker with Ant</a>
+ </dt>
+ <dt>
+ comment, <a href="dgui_template_overallstructure.html">Overall structure</a>
+ </dt>
+ <dt>
+ comparison operators, <a href="dgui_template_exp.html#dgui_template_exp_comparison">Comparison</a>
+ </dt>
+ <dt>
+ compress directive, <a href="ref_directive_compress.html">compress</a>
+ </dt>
+ <dt>
+ concatenate hashes, <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ concatenate sequences, <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ concatenate strings, <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a>
+ </dt>
+ <dt>
+ configuration, <a href="pgui_quickstart_createconfiguration.html">Create a configuration instance</a>
+ </dt>
+ <dt>
+ Configuration, <a href="pgui_config.html">The Configuration</a>
+ </dt>
+ <dt>
+ constant, <a href="dgui_template_exp.html#dgui_template_exp_direct">Specify values directly</a>
+ </dt>
+ <dt>
+ contact, <a href="preface.html#autoid_5">Preface</a>
+ </dt>
+ <dt>
+ containers </dt>
+ <dd><dl>
+ <dt>Java side, <a href="pgui_datamodel_parent.html">Containers</a></dt>
+ </dl></dd>
+ <dt>
+ contains built-in, <a href="ref_builtins_string.html#ref_builtin_contains">contains</a>
+ </dt>
+ <dt>
+ converting between types, <a href="ref_builtins_string.html#ref_builtin_string_date">date, time, datetime</a>,
+<a href="ref_builtins_string.html#ref_builtin_number">number</a>,
+<a href="ref_builtins_number.html#ref_builtin_c">c</a>,
+<a href="ref_builtins_number.html#ref_builtin_string_for_number">string (when used with a numerical value)</a>,
+<a href="ref_builtins_date.html#ref_builtin_string_for_date">string (when used with a date value)</a>,
+<a href="ref_builtins_date.html#ref_builtin_date_datetype">date, time, datetime</a>,
+<a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">string (when used with a boolean value)</a>,
+<a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ custom directive, <a href="dgui_misc_userdefdir.html">Defining your own directives</a>
+ </dt>
+ <dt>
+ custom tags, <a href="pgui_misc_servlet.html#autoid_55">Using FreeMarker with servlets</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_D"></a>
+<h2 class="indexLabel">D</h2>
+<dl>
+ <dt>
+ data-model, <a href="dgui_quickstart_basics.html">Template + data-model = output</a>
+ </dt>
+ <dd><dl>
+ <dt>assembling with Java, <a href="pgui_quickstart_createdatamodel.html">Create a data-model</a></dt>
+ <dt>assembling with Java, without object wrapper, <a href="pgui_datamodel_basics.html">Basics</a></dt>
+ </dl></dd>
+ <dt>
+ date </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_date.html">Built-ins for dates</a></dt>
+ <dt>Java API related difficulties, <a href="pgui_datamodel_scalar.html#autoid_31">Scalars</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ date_format, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ date built-in, <a href="ref_builtins_string.html#ref_builtin_string_date">date, time, datetime</a>,
+<a href="ref_builtins_date.html#ref_builtin_date_datetype">date, time, datetime</a>
+ </dt>
+ <dt>
+ date-time </dt>
+ <dd><dl>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ datetime_format, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ datetime built-in, <a href="ref_builtins_string.html#ref_builtin_string_date">date, time, datetime</a>,
+<a href="ref_builtins_date.html#ref_builtin_date_datetype">date, time, datetime</a>
+ </dt>
+ <dt>
+ default built-in, <a href="ref_depr_builtin.html">List of deprecated built-ins</a>
+ </dt>
+ <dt>
+ default directive, <a href="ref_directive_switch.html">switch, case, default, break</a>
+ </dt>
+ <dt>
+ default value operator, <a href="dgui_template_exp.html#dgui_template_exp_missing_default">Default value operator</a>
+ </dt>
+ <dt>
+ defining macro, <a href="dgui_misc_userdefdir.html#autoid_21">Defining your own directives</a>
+ </dt>
+ <dt>
+ deprecated, <a href="ref_deprecated.html">Deprecated FTL constructs</a>
+ </dt>
+ <dt>
+ directive, <a href="dgui_template_directives.html">Directives</a>,
+<a href="ref_directives.html">Directive Reference</a>
+ </dt>
+ <dd><dl>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_userdefdir">User-defined directives</a></dt>
+ <dt>user-defined, <a href="dgui_misc_userdefdir.html">Defining your own directives</a></dt>
+ </dl></dd>
+ <dt>
+ directives </dt>
+ <dd><dl>
+ <dt>Java side, <a href="pgui_datamodel_directive.html">Directives</a></dt>
+ </dl></dd>
+ <dt>
+ division, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ double built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ download, <a href="preface.html#autoid_5">Preface</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_E"></a>
+<h2 class="indexLabel">E</h2>
+<dl>
+ <dt>
+ else directive, <a href="ref_directive_if.html">if, else, elseif</a>
+ </dt>
+ <dt>
+ elseif directive, <a href="ref_directive_if.html">if, else, elseif</a>
+ </dt>
+ <dt>
+ encoding, <a href="pgui_misc_charset.html">Charset issues</a>,
+<a href="ref_directive_ftl.html">ftl</a>
+ </dt>
+ <dd><dl>
+ <dt>URL, <a href="ref_builtins_string.html#ref_builtin_url">url</a></dt>
+ </dl></dd>
+ <dt>
+ ends_with built-in, <a href="ref_builtins_string.html#ref_builtin_ends_with">ends_with</a>
+ </dt>
+ <dt>
+ error, <a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ error handling, <a href="dgui_template_exp.html#dgui_template_exp_missing">Handling missing values</a>,
+<a href="pgui_config_errorhandling.html">Error handling</a>,
+<a href="ref_directive_attempt.html">attempt, recover</a>
+ </dt>
+ <dt>
+ escape directive, <a href="ref_directive_escape.html">escape, noescape</a>
+ </dt>
+ <dt>
+ escape sequences, <a href="dgui_template_exp.html#dgui_template_exp_direct_string">Strings</a>
+ </dt>
+ <dt>
+ escaping </dt>
+ <dd><dl>
+ <dt>output, <a href="ref_builtins_string.html#ref_builtin_html">html</a>, <a href="ref_builtins_string.html#ref_builtin_rtf">rtf</a>, <a href="ref_builtins_string.html#ref_builtin_xhtml">xhtml</a>, <a href="ref_builtins_string.html#ref_builtin_xml">xml</a></dt>
+ <dt>URL, <a href="ref_builtins_string.html#ref_builtin_url">url</a></dt>
+ </dl></dd>
+ <dt>
+ eval, <a href="ref_builtins_expert.html#ref_builtin_eval">eval</a>
+ </dt>
+ <dt>
+ evaluate string, <a href="ref_builtins_expert.html#ref_builtin_eval">eval</a>
+ </dt>
+ <dt>
+ exception handling, <a href="pgui_config_errorhandling.html">Error handling</a>
+ </dt>
+ <dt>
+ existence test operator, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+ <dt>
+ exists built-in, <a href="ref_depr_builtin.html">List of deprecated built-ins</a>
+ </dt>
+ <dt>
+ expression, <a href="dgui_template_exp.html">Expressions</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_F"></a>
+<h2 class="indexLabel">F</h2>
+<dl>
+ <dt>
+ fallback directive, <a href="ref_directive_visit.html">visit, recurse, fallback</a>
+ </dt>
+ <dt>
+ FAQ, <a href="app_faq.html">FAQ</a>
+ </dt>
+ <dt>
+ first built-in, <a href="ref_builtins_sequence.html#ref_builtin_first">first</a>
+ </dt>
+ <dt>
+ float built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ floor built-in, <a href="ref_builtins_number.html#ref_builtin_rounding">round, floor, ceiling</a>
+ </dt>
+ <dt>
+ flush directive, <a href="ref_directive_flush.html">flush</a>
+ </dt>
+ <dt>
+ format </dt>
+ <dd><dl>
+ <dt>boolean, <a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">string (when used with a boolean value)</a>, <a href="ref_directive_setting.html#autoid_101">setting</a></dt>
+ <dt>date, <a href="ref_builtins_date.html#ref_builtin_string_for_date">string (when used with a date value)</a>, <a href="ref_directive_setting.html#autoid_101">setting</a></dt>
+ <dt>number, <a href="ref_builtins_number.html#ref_builtin_c">c</a>, <a href="ref_builtins_number.html#ref_builtin_string_for_number">string (when used with a numerical value)</a>, <a href="ref_directive_setting.html#ref.setting.number_format">setting</a></dt>
+ </dl></dd>
+ <dt>
+ FTL, <a href="dgui_template_overallstructure.html">Overall structure</a>
+ </dt>
+ <dt>
+ ftl directive, <a href="ref_directive_ftl.html">ftl</a>
+ </dt>
+ <dt>
+ FTL tag, <a href="dgui_template_overallstructure.html">Overall structure</a>,
+<a href="dgui_template_directives.html">Directives</a>
+ </dt>
+ <dt>
+ function directive, <a href="ref_directive_function.html">function, return</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_G"></a>
+<h2 class="indexLabel">G</h2>
+<dl>
+ <dt>
+ get character, <a href="dgui_template_exp.html#dgui_template_exp_get_character">Getting a character</a>
+ </dt>
+ <dt>
+ global directive, <a href="ref_directive_global.html">global</a>
+ </dt>
+ <dt>
+ groups built-in, <a href="ref_builtins_string.html#ref_builtin_groups">groups</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_H"></a>
+<h2 class="indexLabel">H</h2>
+<dl>
+ <dt>
+ handling null-s, <a href="dgui_template_exp.html#dgui_template_exp_missing">Handling missing values</a>
+ </dt>
+ <dt>
+ has_content built-in, <a href="ref_builtins_expert.html#ref_builtin_has_content">has_content</a>
+ </dt>
+ <dt>
+ hash </dt>
+ <dd><dl>
+ <dt>accessing subvariable, <a href="dgui_template_exp.html#dgui_template_exp_var_hash">Retrieving data from a hash</a></dt>
+ <dt>built-ins, <a href="ref_builtins_hash.html">Built-ins for hashes</a></dt>
+ <dt>concatenate, <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">Concatenation</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_parent.html#autoid_32">Containers</a></dt>
+ <dt>key type, <a href="app_faq.html">FAQ</a></dt>
+ <dt>literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_hash">Hashes</a></dt>
+ <dt>modify, <a href="app_faq.html#faq_modify_seq_and_map">FAQ</a></dt>
+ <dt>operations, <a href="dgui_template_exp.html#dgui_template_exp_hashop">Hash operations</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_container">Containers</a></dt>
+ </dl></dd>
+ <dt>
+ header, <a href="ref_directive_ftl.html">ftl</a>
+ </dt>
+ <dt>
+ help, <a href="preface.html#autoid_5">Preface</a>
+ </dt>
+ <dt>
+ homepage, <a href="preface.html#autoid_5">Preface</a>
+ </dt>
+ <dt>
+ html built-in, <a href="ref_builtins_string.html#ref_builtin_html">html</a>
+ </dt>
+ <dt>
+ HTTP, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_I"></a>
+<h2 class="indexLabel">I</h2>
+<dl>
+ <dt>
+ if_exists built-in, <a href="ref_depr_builtin.html">List of deprecated built-ins</a>
+ </dt>
+ <dt>
+ if directive, <a href="ref_directive_if.html">if, else, elseif</a>
+ </dt>
+ <dt>
+ import directive, <a href="ref_directive_import.html">import</a>
+ </dt>
+ <dt>
+ include </dt>
+ <dd><dl>
+ <dt>JSP, <a href="pgui_misc_servlet.html#pgui_misc_servlet_include">Including content from other web application
+ resources</a></dt>
+ <dt>servlet, <a href="pgui_misc_servlet.html#pgui_misc_servlet_include">Including content from other web application
+ resources</a></dt>
+ </dl></dd>
+ <dt>
+ include directive, <a href="ref_directive_include.html">include</a>
+ </dt>
+ <dt>
+ index_of built-in, <a href="ref_builtins_string.html#ref_builtin_index_of">index_of</a>
+ </dt>
+ <dt>
+ install, <a href="app_install.html">Installing FreeMarker</a>
+ </dt>
+ <dt>
+ instantiating variable, <a href="ref_builtins_expert.html#ref_builtin_new">new</a>
+ </dt>
+ <dt>
+ int built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ integer division, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ integer part, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ interpolation, <a href="dgui_template_overallstructure.html">Overall structure</a>,
+<a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a>,
+<a href="dgui_template_valueinsertion.html">Interpolations</a>
+ </dt>
+ <dt>
+ interpret built-in, <a href="ref_builtins_expert.html#ref_builtin_interpret">interpret</a>
+ </dt>
+ <dt>
+ is_... built-in, <a href="ref_builtins_expert.html#ref_builtin_isType">is_...</a>
+ </dt>
+ <dt>
+ is null, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_J"></a>
+<h2 class="indexLabel">J</h2>
+<dl>
+ <dt>
+ j_string built-in, <a href="ref_builtins_string.html#ref_builtin_j_string">j_string</a>
+ </dt>
+ <dt>
+ joining hashes, <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ joining sequences, <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">Concatenation</a>
+ </dt>
+ <dt>
+ joining strings, <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a>
+ </dt>
+ <dt>
+ js_string built-in, <a href="ref_builtins_string.html#ref_builtin_js_string">js_string</a>
+ </dt>
+ <dt>
+ JSP, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>,
+<a href="app_faq.html#faq_jsp_vs_freemarker">FAQ</a>
+ </dt>
+ <dd><dl>
+ <dt>include, <a href="pgui_misc_servlet.html#pgui_misc_servlet_include">Including content from other web application
+ resources</a></dt>
+ <dt>taglib, <a href="pgui_misc_servlet.html#autoid_55">Using FreeMarker with servlets</a>, <a href="pgui_misc_servlet.html#autoid_56">Using FreeMarker with servlets</a></dt>
+ </dl></dd>
+ <dt>
+ jython </dt>
+ <dd><dl>
+ <dt>wrapping, <a href="pgui_misc_jythonwrapper.html">Jython wrapper</a></dt>
+ </dl></dd>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_K"></a>
+<h2 class="indexLabel">K</h2>
+<dl>
+ <dt>
+ keys built-in, <a href="ref_builtins_hash.html#ref_builtin_keys">keys</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_L"></a>
+<h2 class="indexLabel">L</h2>
+<dl>
+ <dt>
+ language, <a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ last_index_of built-in, <a href="ref_builtins_string.html#ref_builtin_last_index_of">last_index_of</a>
+ </dt>
+ <dt>
+ last built-in, <a href="ref_builtins_sequence.html#ref_builtin_last">last</a>
+ </dt>
+ <dt>
+ left_pad built-in, <a href="ref_builtins_string.html#ref_builtin_left_pad">left_pad</a>
+ </dt>
+ <dt>
+ length built-in, <a href="ref_builtins_string.html#ref_builtin_length">length</a>
+ </dt>
+ <dt>
+ libraries, <a href="dgui_misc_namespace.html">Namespaces</a>
+ </dt>
+ <dt>
+ library path, <a href="dgui_misc_namespace.html#autoid_29">Namespaces</a>
+ </dt>
+ <dt>
+ license, <a href="app_license.html">License</a>
+ </dt>
+ <dt>
+ list directive, <a href="ref_directive_list.html">list, break</a>
+ </dt>
+ <dt>
+ literal, <a href="dgui_template_exp.html#dgui_template_exp_direct">Specify values directly</a>
+ </dt>
+ <dd><dl>
+ <dt>boolean, <a href="dgui_template_exp.html#dgui_template_exp_direct_boolean">Booleans</a></dt>
+ <dt>hash, <a href="dgui_template_exp.html#dgui_template_exp_direct_hash">Hashes</a></dt>
+ </dl></dd>
+ <dt>
+ loading templates, <a href="pgui_config_templateloading.html">Template loading</a>
+ </dt>
+ <dt>
+ local directive, <a href="ref_directive_local.html">local</a>
+ </dt>
+ <dt>
+ locale, <a href="ref_directive_setting.html#autoid_101">setting</a>,
+<a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ localization, <a href="ref_directive_include.html#ref_directive_include_localized">Localized lookup</a>
+ </dt>
+ <dt>
+ local variable, <a href="dgui_misc_var.html">Defining variables in the template</a>
+ </dt>
+ <dt>
+ logging, <a href="pgui_misc_logging.html">Logging</a>
+ </dt>
+ <dt>
+ logical operations, <a href="dgui_template_exp.html#dgui_template_exp_logicalop">Logical operations</a>
+ </dt>
+ <dt>
+ long built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ loop variable, <a href="dgui_misc_userdefdir.html#dgui_misc_userdefdir_loopvar">Macros with loop variables</a>,
+<a href="dgui_misc_var.html">Defining variables in the template</a>
+ </dt>
+ <dt>
+ lower_case built-in, <a href="ref_builtins_string.html#ref_builtin_lower_case">lower_case</a>
+ </dt>
+ <dt>
+ lt directive, <a href="ref_directive_t.html">t, lt, rt</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_M"></a>
+<h2 class="indexLabel">M</h2>
+<dl>
+ <dt>
+ macro, <a href="dgui_misc_userdefdir.html">Defining your own directives</a>
+ </dt>
+ <dd><dl>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_userdefdir">User-defined directives</a></dt>
+ </dl></dd>
+ <dt>
+ macro directive, <a href="ref_directive_macro.html">macro, nested, return</a>
+ </dt>
+ <dt>
+ matches built-in, <a href="ref_builtins_string.html#ref_builtin_matches">matches</a>
+ </dt>
+ <dt>
+ math, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ merging, <a href="pgui_quickstart_merge.html">Merging the template with the data-model</a>
+ </dt>
+ <dt>
+ method </dt>
+ <dd><dl>
+ <dt>call, <a href="dgui_template_exp.html#dgui_template_exp_methodcall">Method call</a></dt>
+ <dt>defining with FTL, <a href="ref_directive_function.html">function, return</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_method.html">Methods</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_method">Methods and functions</a></dt>
+ </dl></dd>
+ <dt>
+ missing value test operator, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+ <dt>
+ missing variable, <a href="dgui_template_exp.html#dgui_template_exp_missing">Handling missing values</a>
+ </dt>
+ <dt>
+ Model 2, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>
+ </dt>
+ <dt>
+ modify hashes, <a href="app_faq.html#faq_modify_seq_and_map">FAQ</a>
+ </dt>
+ <dt>
+ modify sequences, <a href="app_faq.html#faq_modify_seq_and_map">FAQ</a>
+ </dt>
+ <dt>
+ modulus, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ multithreading, <a href="pgui_misc_multithreading.html">Multithreading</a>
+ </dt>
+ <dt>
+ Multi-typed value, <a href="dgui_datamodel_basics.html#topic.multitype">Basics</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_N"></a>
+<h2 class="indexLabel">N</h2>
+<dl>
+ <dt>
+ namespace built-in, <a href="ref_builtins_expert.html#ref_builtin_namespace">namespace</a>
+ </dt>
+ <dt>
+ namespaces, <a href="dgui_misc_namespace.html">Namespaces</a>
+ </dt>
+ <dt>
+ nested directive, <a href="ref_directive_macro.html">macro, nested, return</a>
+ </dt>
+ <dt>
+ new built-in, <a href="ref_builtins_expert.html#ref_builtin_new">new</a>
+ </dt>
+ <dt>
+ new FTL syntax, <a href="ref_depr_oldsyntax.html">Old FTL syntax</a>
+ </dt>
+ <dt>
+ node </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_node.html">Built-ins for nodes (for XML)</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_node.html">Node variables</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_node">Nodes</a></dt>
+ </dl></dd>
+ <dt>
+ node_name built-in, <a href="ref_builtins_node.html#ref_builtin_node_name">node_name</a>
+ </dt>
+ <dt>
+ node_namespace built-in, <a href="ref_builtins_node.html#ref_builtin_node_namespace">node_namespace</a>
+ </dt>
+ <dt>
+ node_type built-in, <a href="ref_builtins_node.html#ref_builtin_node_type">node_type</a>
+ </dt>
+ <dt>
+ noescape directive, <a href="ref_directive_escape.html">escape, noescape</a>
+ </dt>
+ <dt>
+ noparse directive, <a href="ref_directive_noparse.html">noparse</a>
+ </dt>
+ <dt>
+ not, <a href="dgui_template_exp.html#dgui_template_exp_logicalop">Logical operations</a>
+ </dt>
+ <dt>
+ nt directive, <a href="ref_directive_nt.html">nt</a>
+ </dt>
+ <dt>
+ null, <a href="dgui_template_exp.html#dgui_template_exp_missing">Handling missing values</a>,
+<a href="app_faq.html#faq_null">FAQ</a>
+ </dt>
+ <dt>
+ number </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_number.html">Built-ins for numbers</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ <dt>literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_number">Numbers</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ number_format, <a href="ref_directive_setting.html#ref.setting.number_format">setting</a>
+ </dt>
+ <dt>
+ number built-in, <a href="ref_builtins_string.html#ref_builtin_number">number</a>
+ </dt>
+ <dt>
+ numerical range expression, <a href="dgui_template_exp.html#dgui_template_exp_direct_seuqence">Sequences</a>
+ </dt>
+ <dt>
+ numerical sequence, <a href="dgui_template_exp.html#dgui_template_exp_direct_seuqence">Sequences</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_O"></a>
+<h2 class="indexLabel">O</h2>
+<dl>
+ <dt>
+ object wrapper, <a href="pgui_datamodel_basics.html">Basics</a>,
+<a href="pgui_datamodel_objectWrapper.html">Object wrappers</a>
+ </dt>
+ <dt>
+ old FTL syntax, <a href="ref_depr_oldsyntax.html">Old FTL syntax</a>
+ </dt>
+ <dt>
+ operator precedence, <a href="dgui_template_exp.html#dgui_template_exp_precedence">Operator precedence</a>
+ </dt>
+ <dt>
+ or, <a href="dgui_template_exp.html#dgui_template_exp_logicalop">Logical operations</a>
+ </dt>
+ <dt>
+ output </dt>
+ <dd><dl>
+ <dt>generate with Java, <a href="pgui_quickstart_merge.html">Merging the template with the data-model</a></dt>
+ </dl></dd>
+ <dt>
+ output charset, <a href="pgui_misc_charset.html#autoid_47">Charset issues</a>,
+<a href="ref_builtins_string.html#ref_builtin_url">url</a>,
+<a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ output encoding, <a href="pgui_misc_charset.html#autoid_47">Charset issues</a>,
+<a href="ref_builtins_string.html#ref_builtin_url">url</a>,
+<a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_P"></a>
+<h2 class="indexLabel">P</h2>
+<dl>
+ <dt>
+ padding, <a href="ref_builtins_string.html#ref_builtin_left_pad">left_pad</a>,
+<a href="ref_builtins_string.html#ref_builtin_right_pad">right_pad</a>
+ </dt>
+ <dt>
+ parent built-in, <a href="ref_builtins_node.html#ref_builtin_parent">parent</a>
+ </dt>
+ <dt>
+ parentheses, <a href="dgui_template_exp.html#dgui_template_exp_parentheses">Parentheses</a>
+ </dt>
+ <dt>
+ path, <a href="pgui_config_templateloading.html#autoid_42">Template loading</a>
+ </dt>
+ <dt>
+ positional parameter passing, <a href="ref_directive_userDefined.html#ref_directive_userDefined_positionalParam">Positional parameter passing</a>
+ </dt>
+ <dt>
+ precedence, <a href="dgui_template_exp.html#dgui_template_exp_precedence">Operator precedence</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_R"></a>
+<h2 class="indexLabel">R</h2>
+<dl>
+ <dt>
+ range expression, <a href="dgui_template_exp.html#dgui_template_exp_direct_seuqence">Sequences</a>
+ </dt>
+ <dt>
+ raw string literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_string">Strings</a>
+ </dt>
+ <dt>
+ recover directive, <a href="ref_directive_attempt.html">attempt, recover</a>
+ </dt>
+ <dt>
+ recurse directive, <a href="ref_directive_visit.html">visit, recurse, fallback</a>
+ </dt>
+ <dt>
+ recursion </dt>
+ <dd><dl>
+ <dt>iterate, <a href="ref_directive_visit.html">visit, recurse, fallback</a></dt>
+ </dl></dd>
+ <dt>
+ regular expression </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_string.html#ref_builtin_string_flags">Common flags</a></dt>
+ </dl></dd>
+ <dt>
+ replace built-in, <a href="ref_builtins_string.html#ref_builtin_replace">replace</a>
+ </dt>
+ <dt>
+ reserved name, <a href="ref_reservednames.html">Reserved names in FTL</a>
+ </dt>
+ <dt>
+ return directive, <a href="ref_directive_macro.html">macro, nested, return</a>,
+<a href="ref_directive_function.html">function, return</a>
+ </dt>
+ <dt>
+ reverse built-in, <a href="ref_builtins_sequence.html#ref_builtin_reverse">reverse</a>
+ </dt>
+ <dt>
+ right_pad built-in, <a href="ref_builtins_string.html#ref_builtin_right_pad">right_pad</a>
+ </dt>
+ <dt>
+ root built-in, <a href="ref_builtins_node.html#ref_builtin_root">root</a>
+ </dt>
+ <dt>
+ round built-in, <a href="ref_builtins_number.html#ref_builtin_rounding">round, floor, ceiling</a>
+ </dt>
+ <dt>
+ rounding, <a href="ref_builtins_number.html#ref_builtin_rounding">round, floor, ceiling</a>
+ </dt>
+ <dt>
+ rt directive, <a href="ref_directive_t.html">t, lt, rt</a>
+ </dt>
+ <dt>
+ rtf built-in, <a href="ref_builtins_string.html#ref_builtin_rtf">rtf</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_S"></a>
+<h2 class="indexLabel">S</h2>
+<dl>
+ <dt>
+ scalar </dt>
+ <dd><dl>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ security, <a href="pgui_misc_secureenv.html">Configuring security policy for FreeMarker</a>
+ </dt>
+ <dt>
+ seq_contains built-in, <a href="ref_builtins_sequence.html#ref_builtin_seq_contains">seq_contains</a>
+ </dt>
+ <dt>
+ seq_index_of built-in, <a href="ref_builtins_sequence.html#ref_builtin_seq_index_of">seq_index_of</a>
+ </dt>
+ <dt>
+ seq_last_index_of built-in, <a href="ref_builtins_sequence.html#ref_builtin_seq_last_index_of">seq_last_index_of</a>
+ </dt>
+ <dt>
+ sequence </dt>
+ <dd><dl>
+ <dt>accessing subvariable, <a href="dgui_template_exp.html#dgui_template_exp_var_sequence">Retrieving data from a sequence</a></dt>
+ <dt>built-ins, <a href="ref_builtins_sequence.html">Built-ins for sequences</a></dt>
+ <dt>concatenate, <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">Concatenation</a></dt>
+ <dt>iterate, <a href="ref_directive_list.html">list, break</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_parent.html#autoid_33">Containers</a></dt>
+ <dt>literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_seuqence">Sequences</a></dt>
+ <dt>modify, <a href="app_faq.html#faq_modify_seq_and_map">FAQ</a></dt>
+ <dt>operations, <a href="dgui_template_exp.html#dgui_template_exp_sequenceop">Sequence operations</a></dt>
+ <dt>slice, <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">Sequence slice</a></dt>
+ <dt>sorting, <a href="ref_builtins_sequence.html#ref_builtin_sort">sort</a>, <a href="ref_builtins_sequence.html#ref_builtin_sort_by">sort_by</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_container">Containers</a></dt>
+ </dl></dd>
+ <dt>
+ sequence slice, <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">Sequence slice</a>
+ </dt>
+ <dt>
+ servlet </dt>
+ <dd><dl>
+ <dt>include, <a href="pgui_misc_servlet.html#pgui_misc_servlet_include">Including content from other web application
+ resources</a></dt>
+ </dl></dd>
+ <dt>
+ Servlet, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>
+ </dt>
+ <dt>
+ setting, <a href="pgui_config_settings.html">Settings</a>
+ </dt>
+ <dt>
+ setting directive, <a href="ref_directive_setting.html">setting</a>
+ </dt>
+ <dt>
+ shared variable, <a href="pgui_config_sharedvariables.html">Shared variables</a>
+ </dt>
+ <dt>
+ short built-in, <a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ size built-in, <a href="ref_builtins_sequence.html#ref_builtin_size">size</a>
+ </dt>
+ <dt>
+ sort_by built-in, <a href="ref_builtins_sequence.html#ref_builtin_sort_by">sort_by</a>
+ </dt>
+ <dt>
+ sort built-in, <a href="ref_builtins_sequence.html#ref_builtin_sort">sort</a>
+ </dt>
+ <dt>
+ special variable, <a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ special variables, <a href="dgui_template_exp.html#dgui_template_exp_var_special">Special variables</a>
+ </dt>
+ <dt>
+ split built-in, <a href="ref_builtins_string.html#ref_builtin_split">split</a>
+ </dt>
+ <dt>
+ square bracket syntax, <a href="dgui_misc_alternativesyntax.html">Alternative (square bracket) syntax</a>
+ </dt>
+ <dt>
+ starts_with built-in, <a href="ref_builtins_string.html#ref_builtin_starts_with">starts_with</a>
+ </dt>
+ <dt>
+ static method </dt>
+ <dd><dl>
+ <dt>accessing from templates, <a href="pgui_misc_beanwrapper.html#autoid_54">Bean wrapper</a></dt>
+ </dl></dd>
+ <dt>
+ stop directive, <a href="ref_directive_stop.html">stop</a>
+ </dt>
+ <dt>
+ storing templates, <a href="pgui_config_templateloading.html">Template loading</a>
+ </dt>
+ <dt>
+ strict syntax, <a href="ref_depr_oldsyntax.html">Old FTL syntax</a>
+ </dt>
+ <dt>
+ string </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_string.html">Built-ins for strings</a></dt>
+ <dt>concatenate, <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a></dt>
+ <dt>interpolation, <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ <dt>literal, <a href="dgui_template_exp.html#dgui_template_exp_direct_string">Strings</a></dt>
+ <dt>operations, <a href="dgui_template_exp.html#dgui_template_exp_stringop">String operations</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ string built-in, <a href="ref_builtins_number.html#ref_builtin_string_for_number">string (when used with a numerical value)</a>,
+<a href="ref_builtins_date.html#ref_builtin_string_for_date">string (when used with a date value)</a>,
+<a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">string (when used with a boolean value)</a>
+ </dt>
+ <dt>
+ Struts, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>
+ </dt>
+ <dt>
+ subsequence, <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">Sequence slice</a>
+ </dt>
+ <dt>
+ substring built-in, <a href="ref_builtins_string.html#ref_builtin_substring">substring</a>
+ </dt>
+ <dt>
+ subtraction, <a href="dgui_template_exp.html#dgui_template_exp_arit">Arithmetical calculations</a>
+ </dt>
+ <dt>
+ subvariable </dt>
+ <dd><dl>
+ <dt>accessing, <a href="dgui_template_exp.html#dgui_template_exp_var_toplevel">Top-level variables</a>, <a href="dgui_template_exp.html#dgui_template_exp_var_hash">Retrieving data from a hash</a>, <a href="dgui_template_exp.html#dgui_template_exp_var_sequence">Retrieving data from a sequence</a></dt>
+ </dl></dd>
+ <dt>
+ switch directive, <a href="ref_directive_switch.html">switch, case, default, break</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_T"></a>
+<h2 class="indexLabel">T</h2>
+<dl>
+ <dt>
+ tabular printing of sequences, <a href="ref_builtins_sequence.html#ref_builtin_chunk">chunk</a>
+ </dt>
+ <dt>
+ tag </dt>
+ <dd><dl>
+ <dt>user-defined, <a href="dgui_misc_userdefdir.html">Defining your own directives</a></dt>
+ </dl></dd>
+ <dt>
+ taglib, <a href="pgui_misc_servlet.html#autoid_55">Using FreeMarker with servlets</a>
+ </dt>
+ <dt>
+ t directive, <a href="ref_directive_t.html">t, lt, rt</a>
+ </dt>
+ <dt>
+ template, <a href="dgui_template.html">The Template</a>
+ </dt>
+ <dd><dl>
+ <dt>Java side, <a href="pgui_quickstart_gettemplate.html">Get the template</a></dt>
+ </dl></dd>
+ <dt>
+ template caching, <a href="pgui_config_templateloading.html#pgui_config_templateloading_caching">Template caching</a>
+ </dt>
+ <dt>
+ template loaders, <a href="pgui_config_templateloading.html#autoid_38">Template loading</a>
+ </dt>
+ <dt>
+ template loading, <a href="pgui_config_templateloading.html">Template loading</a>
+ </dt>
+ <dt>
+ template path, <a href="pgui_config_templateloading.html#autoid_42">Template loading</a>
+ </dt>
+ <dt>
+ temporary variable, <a href="dgui_misc_var.html">Defining variables in the template</a>
+ </dt>
+ <dt>
+ testing for missing, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+ <dt>
+ testing for null, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+ <dt>
+ testing for undefined, <a href="dgui_template_exp.html#dgui_template_exp_missing_test">Missing value test operator</a>
+ </dt>
+ <dt>
+ text, <a href="dgui_template_overallstructure.html">Overall structure</a>
+ </dt>
+ <dt>
+ thread-safety, <a href="pgui_misc_multithreading.html">Multithreading</a>
+ </dt>
+ <dt>
+ time </dt>
+ <dd><dl>
+ <dt>built-ins, <a href="ref_builtins_date.html">Built-ins for dates</a></dt>
+ <dt>Java API related difficulties, <a href="pgui_datamodel_scalar.html#autoid_31">Scalars</a></dt>
+ <dt>Java side, <a href="pgui_datamodel_scalar.html">Scalars</a></dt>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_scalar">Scalars</a></dt>
+ </dl></dd>
+ <dt>
+ time_format, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ time_zone, <a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ time built-in, <a href="ref_builtins_string.html#ref_builtin_string_date">date, time, datetime</a>,
+<a href="ref_builtins_date.html#ref_builtin_date_datetype">date, time, datetime</a>
+ </dt>
+ <dt>
+ transform, <a href="dgui_misc_userdefdir.html">Defining your own directives</a>
+ </dt>
+ <dt>
+ transform directive, <a href="ref_depr_transform.html">Transform directive</a>
+ </dt>
+ <dt>
+ tree nodes, <a href="pgui_datamodel_node.html">Node variables</a>
+ </dt>
+ <dt>
+ trees, <a href="pgui_datamodel_node.html">Node variables</a>
+ </dt>
+ <dt>
+ trim built-in, <a href="ref_builtins_string.html#ref_builtin_trim">trim</a>
+ </dt>
+ <dt>
+ trimmer directives, <a href="ref_directive_t.html">t, lt, rt</a>,
+<a href="ref_directive_nt.html">nt</a>
+ </dt>
+ <dt>
+ type-casting, <a href="ref_builtins_string.html#ref_builtin_string_date">date, time, datetime</a>,
+<a href="ref_builtins_string.html#ref_builtin_number">number</a>,
+<a href="ref_builtins_number.html#ref_builtin_c">c</a>,
+<a href="ref_builtins_number.html#ref_builtin_string_for_number">string (when used with a numerical value)</a>,
+<a href="ref_builtins_date.html#ref_builtin_string_for_date">string (when used with a date value)</a>,
+<a href="ref_builtins_date.html#ref_builtin_date_datetype">date, time, datetime</a>,
+<a href="ref_builtins_boolean.html#ref_builtin_string_for_boolean">string (when used with a boolean value)</a>,
+<a href="ref_builtins_expert.html#ref_builtin_numType">byte, double, float, int, long, short</a>
+ </dt>
+ <dt>
+ type checking, <a href="ref_builtins_expert.html#ref_builtin_isType">is_...</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_U"></a>
+<h2 class="indexLabel">U</h2>
+<dl>
+ <dt>
+ uncap_first built-in, <a href="ref_builtins_string.html#ref_builtin_uncap_first">uncap_first</a>
+ </dt>
+ <dt>
+ undefined variable, <a href="dgui_template_exp.html#dgui_template_exp_missing">Handling missing values</a>
+ </dt>
+ <dt>
+ upper_case built-in, <a href="ref_builtins_string.html#ref_builtin_upper_case">upper_case</a>
+ </dt>
+ <dt>
+ url_escaping_charset, <a href="ref_builtins_string.html#ref_builtin_url">url</a>,
+<a href="ref_directive_setting.html#autoid_101">setting</a>
+ </dt>
+ <dt>
+ url built-in, <a href="ref_builtins_string.html#ref_builtin_url">url</a>
+ </dt>
+ <dt>
+ URL encoding, <a href="ref_builtins_string.html#ref_builtin_url">url</a>
+ </dt>
+ <dt>
+ URL escaping, <a href="ref_builtins_string.html#ref_builtin_url">url</a>
+ </dt>
+ <dt>
+ URL escaping charset, <a href="ref_specvar.html">Special Variable Reference</a>,
+<a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ user-defined directive, <a href="dgui_misc_userdefdir.html">Defining your own directives</a>,
+<a href="ref_directive_userDefined.html">User-defined directive (<@...>)</a>
+ </dt>
+ <dd><dl>
+ <dt>the FTL value type, <a href="dgui_datamodel_types.html#dgui_datamodel_userdefdir">User-defined directives</a></dt>
+ </dl></dd>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_V"></a>
+<h2 class="indexLabel">V</h2>
+<dl>
+ <dt>
+ value, <a href="dgui_datamodel_basics.html#topic.value">What is a value?</a>
+ </dt>
+ <dt>
+ values built-in, <a href="ref_builtins_hash.html#ref_builtin_values">values</a>
+ </dt>
+ <dt>
+ variable, <a href="dgui_misc_var.html">Defining variables in the template</a>
+ </dt>
+ <dt>
+ variables, <a href="pgui_misc_var.html">Variables</a>
+ </dt>
+ <dd><dl>
+ <dt>names, <a href="app_faq.html#faq_legal_variable_names">FAQ</a></dt>
+ </dl></dd>
+ <dt>
+ Velocity, <a href="app_faq.html#faq_jsp_vs_velocity">FAQ</a>
+ </dt>
+ <dt>
+ version, <a href="ref_specvar.html">Special Variable Reference</a>
+ </dt>
+ <dt>
+ visit directive, <a href="ref_directive_visit.html">visit, recurse, fallback</a>
+ </dt>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_W"></a>
+<h2 class="indexLabel">W</h2>
+<dl>
+ <dt>
+ web_safe built-in, <a href="ref_depr_builtin.html">List of deprecated built-ins</a>
+ </dt>
+ <dt>
+ Web application framework, <a href="pgui_misc_servlet.html">Using FreeMarker with servlets</a>
+ </dt>
+ <dt>
+ white-space removal, <a href="dgui_misc_whitespace.html">White-space handling</a>
+ </dt>
+ <dd><dl>
+ <dt>compress, <a href="dgui_misc_whitespace.html#autoid_30">White-space handling</a>, <a href="ref_directive_compress.html">compress</a></dt>
+ <dt>stripping, <a href="dgui_misc_whitespace.html#dgui_misc_whitespace_stripping">White-space stripping</a>, <a href="ref_directive_ftl.html">ftl</a>, <a href="ref_directive_nt.html">nt</a></dt>
+ <dt>trimming, <a href="ref_directive_t.html">t, lt, rt</a>, <a href="ref_directive_nt.html">nt</a></dt>
+ </dl></dd>
+ <dt>
+ word_list built-in, <a href="ref_builtins_string.html#ref_builtin_word_list">word_list</a>
+ </dt>
+ <dt>
+ wrapper, <a href="pgui_datamodel_basics.html">Basics</a>,
+<a href="pgui_datamodel_objectWrapper.html">Object wrappers</a>
+ </dt>
+ <dt>
+ wrapping </dt>
+ <dd><dl>
+ <dt>beans, <a href="pgui_misc_beanwrapper.html">Bean wrapper</a></dt>
+ <dt>jython, <a href="pgui_misc_jythonwrapper.html">Jython wrapper</a></dt>
+ <dt>reflection, <a href="pgui_misc_beanwrapper.html">Bean wrapper</a></dt>
+ </dl></dd>
+</dl></div>
+<div class="indexdiv">
+<a name="idx_X"></a>
+<h2 class="indexLabel">X</h2>
+<dl>
+ <dt>
+ xhtml built-in, <a href="ref_builtins_string.html#ref_builtin_xhtml">xhtml</a>
+ </dt>
+ <dt>
+ XML </dt>
+ <dd><dl>
+ <dt>declarative processing, <a href="xgui_declarative.html">Declarative XML Processing</a></dt>
+ <dt>exposing, <a href="xgui_expose.html">Exposing XML documents</a></dt>
+ <dt>imperative processing, <a href="xgui_imperative.html">Imperative XML processing</a></dt>
+ </dl></dd>
+ <dt>
+ xml built-in, <a href="ref_builtins_string.html#ref_builtin_xml">xml</a>
+ </dt>
+ <dt>
+ XML namespace </dt>
+ <dd><dl>
+ <dt>in imperative processing, <a href="xgui_imperative_learn.html#autoid_72">Learning by example</a></dt>
+ </dl></dd>
+ <dt>
+ XML namespaces </dt>
+ <dd><dl>
+ <dt>in declarative processing, <a href="xgui_declarative_details.html#autoid_77">Details</a></dt>
+ </dl></dd>
+ <dt>
+ XSLT, <a href="xgui_declarative.html">Declarative XML Processing</a>
+ </dt>
+</dl></div>
+<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="gloss.html"><span>Previous</span></a><span class="paging-arrow disabled next"><span>Next</span></span></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app.html b/legacy-tests/build/test/1/app.html
new file mode 100644
index 0000000..029d070
--- /dev/null
+++ b/legacy-tests/build/test/1/app.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-part">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Appendixes - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Appendixes">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app.html">
+<link rel="canonical" href="http://example.com/app.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="ref_depr_numerical_interpolation.html"><span>Previous</span></a><a class="paging-arrow next" href="app_faq.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-part" id="app" itemprop="headline">Appendixes</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="app_faq.html" data-menu-target="app_faq">FAQ</a></li><li><a class="page-menu-link" href="app_install.html" data-menu-target="app_install">Installing FreeMarker</a></li><li><a class="page-menu-link" href="app_build.html" data-menu-target="app_build">Building FreeMarker</a></li><li><a class="page-menu-link" href="app_versions.html" data-menu-target="app_versions">Versions</a><ul><li><a class="page-menu-link" href="versions_2_3_16.html" data-menu-targ [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app_build.html b/legacy-tests/build/test/1/app_build.html
new file mode 100644
index 0000000..cc513b0
--- /dev/null
+++ b/legacy-tests/build/test/1/app_build.html
@@ -0,0 +1,58 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-appendix">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Building FreeMarker - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Building FreeMarker">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app_build.html">
+<link rel="canonical" href="http://example.com/app_build.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes","Building FreeMarker"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="app_install.html"><span>Previous</span></a><a class="paging-arrow next" href="app_versions.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="app_build" itemprop="headline">Building FreeMarker</h1>
+</div></div><p>If you want to modify the source code and rebuild
+ <code class="inline-code">freemarker.jar</code>, you need <a href="http://ant.apache.org/">Ant</a> 1.6.1 (or newer) and JDK
+ 5 (or newer). If these are satisfied, just run Ant from the root
+ directory of the distribution, and it will create the new
+ <code class="inline-code">freemarker.jar</code>. Note that for the very first build
+ you must be on-line, because the build task will download a lot of
+ required dependencies (about 20 MB) into the <code class="inline-code">lib</code>
+ subdirectory of distribution root directory.</p><p>Maybe you should check the new jar file against our test suite.
+ This is done by running Ant with <code class="inline-code">test</code> target (go to
+ the root directory of the distribution, and issue "ant test"). If the
+ test fails, read the resulting <code class="inline-code">.txt</code> file in the
+ <code class="inline-code">build/testcase</code> directory for more details.</p><p>Note that building a full distribution, which includes the
+ FreeMarker Manual and the off-line Web site, is not possible purely from
+ the source code that is included with the distribution. You will have to
+ check out the "docgen" and "site" sub-projects from the SVN repository
+ of FreeMarker for that.</p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="app_install.html"><span>Previous</span></a><a class="paging-arrow next" href="app_versions.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app_faq.html b/legacy-tests/build/test/1/app_faq.html
new file mode 100644
index 0000000..222b0b5
--- /dev/null
+++ b/legacy-tests/build/test/1/app_faq.html
@@ -0,0 +1,1686 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-appendix">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>FAQ - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="FAQ">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app_faq.html">
+<link rel="canonical" href="http://example.com/app_faq.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes","FAQ"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="app.html"><span>Previous</span></a><a class="paging-arrow next" href="app_install.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="app_faq" itemprop="headline">FAQ</h1>
+</div></div> <div class="qandaset">
+
+ <ol>
+ <li>
+ <a href="#faq_jsp_vs_freemarker">
+
+ JSP versus FreeMarker?
+
+
+ </a>
+ </li>
+ <li>
+ <a href="#faq_jsp_vs_velocity">
+
+ Velocity versus FreeMarker?
+
+
+ </a>
+ </li>
+ <li>
+ <a href="#faq_picky_about_missing_vars">
+
+ Why is FreeMarker so picky about <code class="inline-code">null</code>-s
+ and missing variables, and what to do with it?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_4">
+
+ The documentation writes about feature
+ <em>X</em>, but it seems that FreeMarker doesn't
+ know that, or it behaves in a different way as documented, or a
+ bug that was supposedly fixed is still present.
+ </a>
+ </li>
+ <li>
+ <a href="#faq_number_grouping">
+
+ Why does FreeMarker print the numbers with strange
+ formatting (as 1,000,000 or 1 000 000 instead of 1000000)?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_number_decimal_point">
+
+ Why does FreeMarker print bad decimal and/or grouping
+ separator symbol (as 3.14 instead of 3,14)?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_number_boolean_formatting">
+
+ Why does FreeMarker give an error when I try to print a
+ boolean like <code class="inline-code">${aBoolean}</code>, and how to fix
+ it?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_alternative_syntax">
+
+ The <code class="inline-code"><</code> and <code class="inline-code">></code> of
+ FreeMarker tags confuses my editor or the XML parser. What to
+ do?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_legal_variable_names">
+
+ What are the legal variable names?
+
+
+ </a>
+ </li>
+ <li>
+ <a href="#faq_strange_variable_name">
+
+ How can I use variable (macro) names that contain space,
+ dash or other special characters?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_11">
+
+ Why do I get "java.lang.IllegalArgumentException: argument
+ type mismatch" when I try to use <em>X</em> JSP
+ custom tag?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_servlet_include">
+
+ How to include other resources in a way as
+ <code class="inline-code">jsp:include</code> does it?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_13">
+
+ How can I get the parameters to my
+ plain-Java-method/<code class="inline-code">TemplateMethodModelEx</code>/<code class="inline-code">TemplateTransformModel</code>/<code class="inline-code">TemplateDirectiveModel</code>
+ implementation as plain
+ <code class="inline-code">java.lang.*</code>/<code class="inline-code">java.util.*</code>
+ objects?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_14">
+
+ Why I can't use non-string key in the
+ <code class="inline-code">myMap[myKey]</code> expression? And what to do
+ now?
+
+
+ </a>
+ </li>
+ <li>
+ <a href="#faq_simple_map">
+
+ When I list the contents of a map (a hash) with
+ <code class="inline-code">?keys</code>/<code class="inline-code">?values</code>, I get the
+ <code class="inline-code">java.util.Map</code> methods mixed with the real map
+ entries. Of course, I only want to get the map entries.
+ </a>
+ </li>
+ <li>
+ <a href="#faq_modify_seq_and_map">
+
+ How can I modify sequences (lists) and hashes (maps) in
+ FreeMarker templates?
+
+
+
+
+
+
+
+
+ </a>
+ </li>
+ <li>
+ <a href="#faq_null">
+
+ What about <code class="inline-code">null</code> and the FreeMarker
+ template language?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_18">
+
+ How can I use the output of a directive (macro) in
+ expressions (as a parameter to another directive)?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_19">
+
+ Why do I have ``?''-s in the output instead of character
+ <em>X</em>?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_20">
+
+ How to retrieve values calculated in templates after
+ template execution done?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_implement_function_or_macro_in_java">
+
+ How to implement a function or macro in Java Language
+ instead of in the template language?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_22">
+
+ Why is FreeMarker logging suppressed for my
+ application?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_23">
+
+ In my Servlet
+ based application, how do I show a nice error page instead of a
+ stack trace when error occurs during template processing?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_24">
+
+ I'm using a visual HTML editor that mangles template tags.
+ Will you change the template language syntax to accommodate my
+ editor?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_25">
+
+ How fast is FreeMarker? Is it true that 2.x is slower than
+ 1.x (FreeMarker classic)?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_26">
+
+ How can my Java classes ask a template for information about
+ its structure (e.g. a list of all the variables)?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_27">
+
+ Will you ever provide backward compatibility?
+ </a>
+ </li>
+ <li>
+ <a href="#faq_question_28">
+
+ If we distribute FreeMarker with our product, do we have to
+ release the source code for our product?
+ </a>
+ </li>
+ </ol>
+ <dl>
+
+
+
+ <dt class="question" id="faq_jsp_vs_freemarker">
+ 1.
+ JSP versus FreeMarker?
+
+
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Note: JSP 1.x was really bad as an MVC template engine
+ because it was not made for that, so I don't deal with that here.
+ We compare FreeMarker with the JSP 2.0 + JSTL combo.</p>
+
+ <p>FreeMarker Pros:</p>
+
+ <ul>
+ <li>
+ <p>FreeMarker is not tied to Servlets, networking or the
+ Web; it is just a class library to generate text output by
+ merging a template with Java objects (the data-model). You can
+ execute templates anywhere and anytime; no HTTP request
+ forwarding or similar tricks needed, no Servlet environment
+ needed at all. Because of this you can easily integrate it
+ into any system.</p>
+ </li>
+
+ <li>
+ <p>No servlet specific scopes and other highly technical
+ things in templates. It was made for MVC from the beginning,
+ it focuses only on the presentation.</p>
+ </li>
+
+ <li>
+ <p>You can load the templates from anywhere; from the class
+ path, from a data-base, etc.</p>
+ </li>
+
+ <li>
+ <p>Locale sensitive number and date formatting by default.
+ Since we mostly output for a human audience all you need to do
+ is just write <code class="inline-code">${x}</code> rather than
+ <code class="inline-code"><fmt:formatNumber value="${x}" /></code>.
+ You can easily switch this behavior and output non-localized
+ numbers by default.</p>
+ </li>
+
+ <li>
+ <p>Easier to define ad-hoc macros and functions.</p>
+ </li>
+
+ <li>
+ <p>No sweeping errors under the carpet. Missing variables
+ will cause an error by default, and not silently default to
+ arbitrary values. Also, <code class="inline-code">null</code>-s are not
+ treated silently as 0/false/empty string. <a href="#faq_picky_about_missing_vars">See more about this
+ here...</a></p>
+ </li>
+
+ <li>
+ <p>``Object wrapping''. This lets you show the objects to
+ templates in a customized, presentation oriented way (e.g.
+ <a href="xgui_imperative_learn.html">see here</a> how a
+ W3C DOM nodes can be seen by templates using this
+ technology.)</p>
+ </li>
+
+ <li>
+ <p>Macros and functions are just variables (compare it to
+ how JSP custom tags work), so they can be easily passed around
+ as parameter values, put into the data-model, ...etc, just
+ like any other value.</p>
+ </li>
+
+ <li>
+ <p>Easier to read, more terse syntax. For example:
+ <code class="inline-code"><#if x>...</#if></code> instead of
+ <code class="inline-code"><c:if
+ test="${x}">...</c:if></code></p>
+ </li>
+
+ <li>
+ <p>Virtually unnoticeable delay when visiting a page for
+ the first time (or after it was changed), because no expensive
+ compilation happens.</p>
+ </li>
+ </ul>
+
+ <p>FreeMarker Cons:</p>
+
+ <ul>
+ <li>
+ <p>Not a ``standard''. There are fewer tools and IDE
+ integrations, fewer developers knows it and there's much less
+ industry support in general. (However, JSP tag libraries work
+ without modification in FreeMarker templates, if they are not
+ using <code class="inline-code">.tag</code> files.)</p>
+ </li>
+
+ <li>
+ <p>Since macros and function are just variables, incorrect
+ directive and parameter names and missing required parameters
+ can be detected only on runtime.</p>
+ </li>
+
+ <li>
+ <p>Its syntax doesn't follow the HTML/XML rules appart from
+ some visual similarity, which is confusing for new users.
+ (It's the price of the terseness...)</p>
+ </li>
+
+ <li>
+ <p>Doesn't work with JSF. (It could work technically, but
+ nobody has implemented that yet.)</p>
+ </li>
+ </ul>
+
+ <p>You may read this if you are considering replacing JSP with
+ FreeMarker: <a href="pgui_misc_servlet.html#pgui_misc_servlet_model2">Programmer's Guide/Miscellaneous/Using FreeMarker with servlets/Using FreeMarker for ``Model 2''</a></p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_jsp_vs_velocity">
+ 2.
+ Velocity versus FreeMarker?
+
+
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p><a href="http://jakarta.apache.org/velocity/index.html">Velocity</a>
+ is a simpler, more lightweight tool. Thus, it does not address
+ many tasks that FreeMarker does, and its template language is less
+ powerful in general, but it is simpler; visit <a href="http://freemarker.org/fmVsVel.html">http://freemarker.org/fmVsVel.html</a>
+ for details. Currently (2005) Velocity has wider third party
+ support and larger user community.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_picky_about_missing_vars">
+ 3.
+ Why is FreeMarker so picky about <code class="inline-code">null</code>-s
+ and missing variables, and what to do with it?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>To recapitulate what's this entry is about: FreeMarker by
+ default treats an attempt to access a non-existent variable or a
+ <code class="inline-code">null</code> value (<a href="#faq_null">this two
+ is the same for FreeMarker</a>) as error, which aborts the
+ template execution.</p>
+
+ <p>First of all, you should understand the reason of being
+ picky. Most scripting languages and template languages are rather
+ forgiving with missing variables (and with
+ <code class="inline-code">null</code>-s), and they usually treat them as empty
+ string and/or 0 and/or logical false. This behavior has several
+ problems:</p>
+
+ <ul>
+ <li>
+ <p>It potentially hiders accidental mistakes, like a typo
+ in a variable name, or when the template author refers to a
+ variable that the programmer doesn't put into the data-model,
+ or for which the programmer uses a different name. Human is
+ prone to do such accidental mistakes, computers are not, so
+ missing this opportunity that the template engine can show
+ these errors is a bad business. Even if you very carefully
+ check the output of the templates during development, it is
+ easy to look over mistakes like <code class="inline-code"><#if
+ hasDetp><em class="code-color">print dept
+ here...</em></#if></code>, which would then
+ silently never print the dept of the visitor, since you have
+ mistyped the variable name (it should be
+ <code class="inline-code">hasDept</code>). Also think about maintenance,
+ when you later modify your application... most probably you
+ will not re-check templates that carefully each time.</p>
+ </li>
+
+ <li>
+ <p>Makes dangerous assumptions. The script language or
+ template engine knows nothing about the application domain, so
+ when it decides the value of something it don't know to be
+ 0/false, it is a quite irresponsible and arbitrary thing. Just
+ because it is not know what's your current bank account
+ balance, can we just say it is $0 (and how easy it is to
+ accidentally write <code class="inline-code">Balance: ${balanace}</code>)?
+ Just because it is not known if a patient has penicillin
+ allergy, we can just say he/she doesn't have (and how easy it
+ is to accidentally write <code class="inline-code"><#if
+ hasPenicilinAllergy><em class="code-color">Warning...</em><#else><em class="code-color">Allow...</em></#if></code>;
+ there is a typo in this, if you didn't see)? Just consider the
+ implications of such mistakes for a moment. They can be quite
+ severe and troubling. Showing an error page is often better
+ than showing incorrect information that formally looks
+ good.</p>
+ </li>
+ </ul>
+
+ <p>Being not picky is mostly sweeping under the carpet in this
+ case (not facing with the problems), which of course most people
+ feels more convenient, but still... we believe that in most cases
+ being strict will save your time and increase your software
+ quality in the long run.</p>
+
+ <p>On the other hand, we recognize that there are cases where
+ you don't want FreeMarker to be that picky with good reason, and
+ there is solution for them:</p>
+
+ <ul>
+ <li>
+ <p>It's often normal that your data-model contains
+ <code class="inline-code">null</code>-s or have optional variables. In such
+ cases use <a href="dgui_template_exp.html#dgui_template_exp_missing">these
+ operators</a>. If you use them too often, try to rethink
+ your data-model, because depending on them too much is not
+ just results in awkward verbose templates, but increases the
+ probability of hiding errors and printing arbitrary incorrect
+ output (for the reasons described earlier).</p>
+ </li>
+
+ <li>
+ <p>On a production server you may rather want to show an
+ incomplete/damaged page than an error page. In this case you
+ can <a href="pgui_config_errorhandling.html">use other error
+ handler</a> than the default. Error handlers can be made
+ that rather skip the problematic part than abort the whole
+ page rendering. Note, however, that although the error
+ handlers don't give arbitrary default values to variables, for
+ pages that show critical information it's maybe still better
+ to show an error page. (Another feature you may interested in:
+ <a href="ref_directive_attempt.html">the
+ <code>attempt</code>/<code>recover</code>
+ directives</a>)</p>
+ </li>
+ </ul>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 4.
+ The documentation writes about feature
+ <em>X</em>, but it seems that FreeMarker doesn't
+ know that, or it behaves in a different way as documented, or a
+ bug that was supposedly fixed is still present.
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Are you sure that you are using the documentation written
+ for the same version of FreeMarker that you actually use?
+ Especially, note that our online documentation is for the latest
+ usable FreeMarker release. You may use an older release.</p>
+
+ <p>Are you sure that the Java class loader finds the same
+ <code class="inline-code">freemarker.jar</code> that you expect to use? Maybe
+ there is an older version of <code class="inline-code">freemarker.jar</code>
+ around (such as in the Ant <code class="inline-code">lib</code> directory),
+ which has higher priority. To check this, try to print the version
+ number in a template with <code class="inline-code">${.version}</code>. If it
+ dies with ``Unknown built-in variable: version'' error message,
+ then you use a release before 2.3-final or 2.2.8, but you can
+ still try to get the version number in the Java code of your
+ application with
+ <code class="inline-code">Configuration.getVersionNumber()</code>. If this
+ method is not present either, then you are using an early
+ 2.3-preview, or a version before 2.2.6.</p>
+
+ <p>If you think that the documentation or FreeMarker is wrong,
+ please report it using the bug tracker, or the mailing list, or
+ the forums on <a href="http://sourceforge.net/projects/freemarker/">http://sourceforge.net/projects/freemarker/</a>.
+ Thank you!</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_number_grouping">
+ 5.
+ Why does FreeMarker print the numbers with strange
+ formatting (as 1,000,000 or 1 000 000 instead of 1000000)?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>FreeMarker uses the locale-sensitive number formatting
+ capability of the Java platform. The default number format for
+ your locale may uses grouping or other unwanted formatting. To
+ prevent this, you have to override the number format suggested by
+ the Java platform with the <code class="inline-code">number_format</code> <a href="pgui_config_settings.html">FreeMarker setting</a>. For
+ example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">cfg.setNumberFormat("0.######"); // now it will print 1000000
+// where cfg is a freemarker.template.Configuration object</pre></div>
+
+ <p>Note however than humans often find it hard to read big
+ numbers without grouping separator. So in general it is
+ recommended to keep them, and in cases where the numbers are for
+ ''computer audience'' that is confused on the grouping separators,
+ use the <a href="ref_builtins_number.html#ref_builtin_c"><code>c</code>
+ built-in</a>. For example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><a href="/shop/productdetails?id=${<strong>product.id?c</strong>}">Details...</a></pre></div>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_number_decimal_point">
+ 6.
+ Why does FreeMarker print bad decimal and/or grouping
+ separator symbol (as 3.14 instead of 3,14)?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Different countries use different decimal/grouping separator
+ symbols. If you see incorrect symbols, then probably your locale
+ is not set properly. Set the default locale of the JVM or override
+ the default locale with the <code class="inline-code">locale</code> <a href="pgui_config_settings.html">FreeMarker setting</a>. For
+ example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">cfg.setLocale(java.util.Locale.ITALY);
+// where cfg is a freemarker.template.Configuration object</pre></div>
+
+ <p>However, sometimes you want to output a number not for human
+ audience, but for ``computer audience'' (like you want to print a
+ size in CSS), in which case you must use dot as decimal separator,
+ regardless of the locale (language) of the page. For that use the
+ <a href="ref_builtins_number.html#ref_builtin_c"><code>c</code>
+ built-in</a>, for example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">font-size: ${<strong>fontSize?c</strong>}pt;</pre></div>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_number_boolean_formatting">
+ 7.
+ Why does FreeMarker give an error when I try to print a
+ boolean like <code class="inline-code">${aBoolean}</code>, and how to fix
+ it?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Unlike numbers, booleans has no commonly accepted format,
+ not even a common format within the same page. Like when you show
+ on a HTML page if a product is washable, you will hardly want to
+ show for the visitor "Washable: true", but rather "Washable: yes".
+ So we force the template author (by <code class="inline-code">${washable}</code>
+ causing error) to find out with his human knowledge how the
+ boolean value should be shown at the given place. The common way
+ of formatting a boolean is like <code class="inline-code">${washable?string("yes",
+ "no")}</code>, <code class="inline-code">${caching?string("Enabled",
+ "Disabled")}</code>, <code class="inline-code">${heating?string("on",
+ "off")}</code>, etc. However, for generating source code
+ <code class="inline-code">${washable?string("true", "false")}</code> would be
+ very often used, so <code class="inline-code">${washable?string}</code> (i.e.,
+ omitting the parameter list) is equivalent with that.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_alternative_syntax">
+ 8.
+ The <code class="inline-code"><</code> and <code class="inline-code">></code> of
+ FreeMarker tags confuses my editor or the XML parser. What to
+ do?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Starting from FreeMarker 2.3.4 you can use
+ <code class="inline-code">[</code> and <code class="inline-code">]</code> instead of
+ <code class="inline-code"><</code> and <code class="inline-code">></code>. For more
+ details <a href="dgui_misc_alternativesyntax.html">read
+ this...</a></p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_legal_variable_names">
+ 9.
+ What are the legal variable names?
+
+
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>FreeMarker has no limitations regarding the characters used
+ in variable names, nor regarding the length of the variable names,
+ but for your convenience try to chose variable names that can be
+ used with the simple variable reference expressions (see it <a href="dgui_template_exp.html#dgui_template_exp_var_toplevel">here</a>). If you have
+ to choose a more extreme variable name, that's not a bid problem
+ either: <a href="#faq_strange_variable_name">see
+ here</a>.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_strange_variable_name">
+ 10.
+ How can I use variable (macro) names that contain space,
+ dash or other special characters?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>If you have a variable with strange name, such as
+ <code class="inline-code">foo-bar</code>, FreeMarker will misinterpret what do
+ you want when you write thing as <code class="inline-code">${foo-bar}</code>. In
+ this concrete case, it will believe that you want subtract the
+ value of <code class="inline-code">bar</code> from <code class="inline-code">foo</code>. This
+ FAQ entry explains how to handle situations like this.</p>
+
+ <p>First of all it should be clean that these are just
+ syntactical problems. FreeMarker has no limitations regarding the
+ characters used in variable names, nor regarding the length of the
+ variable names, but sometimes you need to use syntactical
+ tricks.</p>
+
+ <p>If you want to read the variable: Use the square bracket
+ syntax. An example of square bracket syntax is
+ <code class="inline-code">baaz["foo"]</code>, which is equivalent with
+ <code class="inline-code">baaz.foo</code>. As the subvariable name with the
+ square bracket syntax is a string literal (in fact, arbitrary
+ expression), it let you write <code class="inline-code">baaz["foo-bar"]</code>.
+ Now you may say that it can be used for hash subvariables only.
+ Yes, but top-level variables are accessible through special hash
+ variable <code class="inline-code">.vars</code>. For example,
+ <code class="inline-code">foo</code> is equivalent with
+ <code class="inline-code">.vars["foo"]</code>. So you can also write
+ <code class="inline-code">.vars["foo-bar"]</code>. Naturally, this trick works
+ with macro invocations too:
+ <code class="inline-code"><@.vars["foo-bar"]/></code></p>
+
+ <p>If you want to create or modify the variable: All directives
+ that let you create or modify a variable (such as
+ <code class="inline-code">assign</code>, <code class="inline-code">local</code>,
+ <code class="inline-code">global</code>, <code class="inline-code">macro</code>,
+ <code class="inline-code">function</code>, etc.) allows the quotation of the
+ destination variable name. For example, <code class="inline-code"><#assign foo =
+ 1></code> is the same as <code class="inline-code"><#assign "foo" =
+ 1></code>. So you can write things like <code class="inline-code"><#assign
+ "foo-bar" = 1></code> and <code class="inline-code"><#macro
+ "foo-bar"></code>.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 11.
+ Why do I get "java.lang.IllegalArgumentException: argument
+ type mismatch" when I try to use <em>X</em> JSP
+ custom tag?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>On JSP pages you quote all parameter (attribute) values, it
+ does not mater if the type of the parameter is string or boolean
+ or number. But since custom tags are accessible in FTL templates
+ as plain user-defined FTL directives, you have to use the FTL
+ syntax rules inside the custom tags, not the JSP rules. Thus,
+ according to FTL rules, you must not quote boolean and numerical
+ parameter values, or they are interpreted as string values, and
+ this will cause a type mismatch error when FreeMarker tries to
+ pass the value to the custom tag that expects non-string
+ value.</p>
+
+ <p>For example, the <code class="inline-code">flush</code> parameter to
+ Struts Tiles <code class="inline-code">insert</code> tag is boolean. In JSP the
+ correct syntax was:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><tiles:insert page="/layout.jsp" <strong>flush="true"</strong>/>
+<em>...</em></pre></div>
+
+ <p>but in FTL you should write:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@tiles.insert page="/layout.ftl" <strong>flush=true</strong>/>
+<em>...</em></pre></div>
+
+ <p>Also, for similar reasons, this is wrong:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><tiles:insert page="/layout.jsp" <strong>flush="${needFlushing}"</strong>/>
+<em>...</em></pre></div>
+
+ <p>and you should write:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><tiles:insert page="/layout.jsp" <strong>flush=needFlushing</strong>/>
+<em>...</em></pre></div>
+
+ <p>(Not <code class="inline-code">flush=${needFlushing}</code>!)</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_servlet_include">
+ 12.
+ How to include other resources in a way as
+ <code class="inline-code">jsp:include</code> does it?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Not with <code class="inline-code"><#include ...></code>, as that
+ just includes another FreeMarker template without involving the
+ Servlet container.</p>
+
+ <p>Since the inclusion method you look for is Servlet-related,
+ and pure FreeMarker is unaware of Servlets or even HTTP, it's the
+ Web Application Framework that decides if you can do this and if
+ so how. For example, in Struts 2 you can do this like this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@s.include value="/WEB-INF/just-an-example.jspf" /></pre></div>
+
+ <p>If the FreeMarker support of the Web Application Framework
+ is based on
+ <code class="inline-code">freemarker.ext.servlet.FreemarkerServlet</code>, then
+ you can also do this (since FreeMarker 2.3.15):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@include_page path="/WEB-INF/just-an-example.jspf" /></pre></div>
+
+ <p>but if the Web Application Framework provides its own
+ solution, then you may prefer that, after all it may does
+ something special.</p>
+
+ <p>For more information about <code class="inline-code">include_page</code>
+ <a href="pgui_misc_servlet.html#pgui_misc_servlet_include">read
+ this...</a></p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 13.
+ How can I get the parameters to my
+ plain-Java-method/<code class="inline-code">TemplateMethodModelEx</code>/<code class="inline-code">TemplateTransformModel</code>/<code class="inline-code">TemplateDirectiveModel</code>
+ implementation as plain
+ <code class="inline-code">java.lang.*</code>/<code class="inline-code">java.util.*</code>
+ objects?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Unfortunately, there is no simple general-purpose solution
+ for this problem. The problem is that FreeMarker object wrapping
+ is very flexible, which is good when you access variables from
+ templates, but makes unwrapping on the Java side a tricky
+ question. For example, it is possible to wrap a
+ non-<code class="inline-code">java.util.Map</code> object as
+ <code class="inline-code">TemplateHashModel</code> (FTL hash variable). But
+ then, it can't be unwrapped to <code class="inline-code">java.util.Map</code>,
+ since there is no wrapped <code class="inline-code">java.util.Map</code> around
+ at all.</p>
+
+ <p>So what to do then? Basically there are two cases:</p>
+
+ <ul>
+ <li>
+ <p>Directives and methods that are written for presentation
+ purposes (like kind of ``tools'' for helping FreeMarker
+ templates) should declare their arguments as
+ <code class="inline-code">TemplateModel</code>-s and the more specific sub
+ interfaces of that. After all, the object wrapping is about
+ apparently transforming the data-model to something that
+ serves the purpose of the presentation layer, and these
+ methods are part of the presentation layer.</p>
+ </li>
+
+ <li>
+ <p>Methods that are not for presentation related tasks (but
+ for business logic and like) should be implemented as plain
+ Java methods, and should not use any FreeMarker specific
+ classes at all, since according the MVC paradigm they must be
+ independent of the presentation technology (FreeMarker). If
+ such a method is called from a template, then it is the
+ responsibility of the <a href="pgui_datamodel_objectWrapper.html">object wrapper</a>
+ to ensure the conversion of the arguments to the proper type.
+ If you use the <code class="inline-code">DefaultObjectWrapper</code> or the
+ <a href="pgui_misc_beanwrapper.html"><code>BeansWrapper</code></a>
+ then this will happen automatically (but be sure you are using
+ at least FreeMarker 2.3.3). Furthermore if you use
+ <code class="inline-code">BeansWrapper</code>, then the method will surely
+ get exactly the same instance that was earlier wrapped (as far
+ as it was wrapped by the
+ <code class="inline-code">BeansWrapper</code>).</p>
+ </li>
+ </ul>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 14.
+ Why I can't use non-string key in the
+ <code class="inline-code">myMap[myKey]</code> expression? And what to do
+ now?
+
+
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>The ``hash'' type of the FreeMarker Template Language (FTL)
+ is not the same as Java's <code class="inline-code">Map</code>. FTL's hash is an
+ associative array too, but it uses string keys exclusively. This
+ is because it was introduced for subvariables (as
+ <code class="inline-code">password</code> in <code class="inline-code">user.password</code>,
+ which is the same as <code class="inline-code">user["password"]</code>), and
+ variable names are strings.</p>
+
+ <p>So FTL's hashes are not general purpose associate arrays
+ that could be used for looking up values with keys of arbitrary
+ type. FTL is presentation oriented language, and it has no feature
+ dedicated for that purpose. It has, however, methods. Methods are
+ part of the data-model, and they can do all kind of fancy
+ data-model related calculations, so of course you can add some
+ methods to the data-model for <code class="inline-code">Map</code> lookup. The
+ bad news is that the building of the data-model, as it's an
+ application specific issue, is the task of the programmers who use
+ FreeMarker, so it's their task to ensure that such methods are
+ present there to serve the template authors. (However, when
+ template authors need to call methods that are not about
+ presentation, then consider if the data-model is simple enough.
+ Maybe you should push some calculations back to the data-model
+ building phase. Ideally the data-model contains what should be
+ displayed, and not something that serves as the base of further
+ calculations.)</p>
+
+ <p>If you read the programmer's guide, then you know that
+ technically, the data-model is a tree of
+ <code class="inline-code">freemarker.template.TemplateModel</code> objects. The
+ building of the data-model usually (but not necessary) happens by
+ automatically wrapping (enclosing) plain Java objects into
+ <code class="inline-code">TemplateModel</code> objects. The object that does
+ this wrapping is the object wrapper, and it's specified when you
+ configure FreeMarker. FreeMarker comes with a few object wrapper
+ implementations out-of-the-box, and probably the most widely used
+ of them is <a href="pgui_misc_beanwrapper.html"><code>freemarker.ext.beans.BeansWrapper</code></a>.
+ If you use an instance of this as the object wrapper, then
+ <code class="inline-code">java.util.Map</code>-s you put into the data-model
+ will also act as a method, so you can write
+ <code class="inline-code">myMap(myKey)</code> in the template, that will
+ internally call <code class="inline-code">Map.get(myKey)</code>. There will be
+ no restriction regarding the type of <code class="inline-code">myKey</code>, as
+ <code class="inline-code">Map.get(Object key)</code> has no such restriction. If
+ the value of <code class="inline-code">myKey</code> was wrapped with
+ <code class="inline-code">BeansWrapper</code> or other object wrapper whose
+ wrapped objects support unwrapping, or it is given as literal in
+ the template, then the value will be automatically unwrapped to
+ plain Java object before the actual invocation of the
+ <code class="inline-code">Map.get(Object key)</code> method, so it will not be
+ invoked with <code class="inline-code">TemplateModel</code>-s.</p>
+
+ <p>But there still will be a problem. Java's
+ <code class="inline-code">Map</code> is particular about the exact class of the
+ key, so for numerical keys calculated inside the templates you
+ will have to cast them to the proper Java type, otherwise the item
+ will not be found. For example if you use
+ <code class="inline-code">Integer</code> keys in a Map, then you have to write
+ <code class="inline-code">${myMap.get(123?int)}</code>. This is an ugly effect
+ caused by that FTL's deliberately simplified type system just has
+ a single numerical type, while Java distinguishes a lot of
+ numerical types. (Ideally, in the above case, the programmers
+ ensure that the <code class="inline-code">get</code> method automatically
+ converts the key to <code class="inline-code">Integer</code>, so it's not the
+ problem of the template author. This can be done with wrapper
+ customization, but the wrapper has to know that the particular
+ <code class="inline-code">Map</code> object uses <code class="inline-code">Integer</code>
+ keys, which assumes application specific knowledge.) Note that the
+ casting is not needed when the key value comes directly from the
+ data-model (i.e. you didn't modified its value with arithmetical
+ caluclations in the template), including the case when it's the
+ return value of a method, and it was of the proper class before
+ wrapping, because then the result of the unwrapping will be of the
+ original type.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_simple_map">
+ 15.
+ When I list the contents of a map (a hash) with
+ <code class="inline-code">?keys</code>/<code class="inline-code">?values</code>, I get the
+ <code class="inline-code">java.util.Map</code> methods mixed with the real map
+ entries. Of course, I only want to get the map entries.
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Certainly you are using <code class="inline-code">BeansWrapper</code> as
+ your object wrapper, or a custom subclass of it, and the
+ <code class="inline-code">simpleMapWrapper</code> property of that is left to
+ <code class="inline-code">false</code>. Unfortunatelly, it's the default (for
+ backward compatibility), so you have to explicitly set it to
+ <code class="inline-code">true</code> where you create the object
+ wrapper.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_modify_seq_and_map">
+ 16.
+ How can I modify sequences (lists) and hashes (maps) in
+ FreeMarker templates?
+
+
+
+
+
+
+
+
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>First of all, you may don't want to modify the
+ sequence/hash, just concatenate (add) two or more of them, which
+ results in a new sequence/hash, rather than modifying an existing
+ one. In this case use the <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">sequence
+ concatenation</a> and <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">hash concatenation
+ operators</a>. Also, you may use the <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">subsequence
+ operator</a> instead of removing sequence items. However, be
+ aware of the performance implications: these operations are fast,
+ but the hashes/sequences that are the result of many subseqent
+ applications of these operations (i.e. when you use the result of
+ the operation as the input of yet another operation, and so on)
+ will be slow to read.</p>
+
+ <p>Now if you still want to modify sequences/hashes, then read
+ on...</p>
+
+ <p>The FreeMarkes Template Language doesn't support the
+ modification of sequences/hashes. It's for displaying already
+ calculated things, not for calculating data. Keep templates
+ simple. But don't give it up, you will see some advices and tricks
+ bellow.</p>
+
+ <p>The best is if you can divide the work between the
+ data-model builder program and the template so that the template
+ doesn't need to modify sequences/hashes. Maybe if you rethink your
+ data-model, you will realize this is possible. But, seldom there
+ are cases where you need to modify sequences/hashes for some
+ complex but purely presentation related algorithms. It seldom
+ happens, so think twice whether that calculation (or parts of it)
+ rather belongs to the data-model domain than to the presentation
+ domain. Let's assume you are sure it belongs to the presentation
+ domain. For example, you want to display a keyword index on some
+ very smart way, whose algorithm need you to create and write some
+ sequence variables. Then you should do something like this (ugly
+ situations has ugly solutions...):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign caculatedResults =
+ 'com.example.foo.SmartKeywordIndexHelper'?new().calculate(keywords)>
+<#-- some simple algorithms comes here, like: -->
+<ul>
+ <#list caculatedResults as kw>
+ <li><a href="${kw.link}">${kw.word}</a>
+ </#list>
+</ul></pre></div>
+
+ <p>That is, you move out the complex part of the presentation
+ task from the template into Java code. Note that it doesn't affect
+ the data-model, so the presentation is still kept separated from
+ other the other application logic. Of course the drawback is that
+ for this the template author will need the help of a Java
+ programmer, but for complex algorithms that's probably needed
+ anyway.</p>
+
+ <p>Now, if you still say you need to modify sequences/hashes
+ directly with the FreeMarker template, here are two solutions, but
+ please read the warning after them:</p>
+
+ <ul>
+ <li>
+ <p>You can write a <code class="inline-code">TemplateMethodModelEx</code>
+ and <code class="inline-code">TemplateDirectiveModel</code> implementation
+ that can modify certain types of sequences/hashes. Just
+ certain types, because
+ <code class="inline-code">TemplateSequenceModel</code> and
+ <code class="inline-code">TemplateHashModel</code> doesn't have methods for
+ modification, so you will need the sequence or hash to
+ implement some additional methods. An example of this solution
+ can be seen in FMPP. It allows you to do things like this
+ (<code class="inline-code">pp</code> stores the services provided by FMPP
+ for templates):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign a = pp.newWritableSequence()>
+<@pp.add seq=a value="red" /></pre></div>
+
+ <p>The <code class="inline-code">pp.add</code> directive works only with
+ sequences that were created with
+ <code class="inline-code">pp.newWritableSequence()</code>. So for example
+ the template author can't modify a sequence that comes from
+ the data-model with this.</p>
+ </li>
+
+ <li>
+ <p>A sequence can have some methods/directives if you use a
+ customized wrapper (so you can <code class="inline-code"><@myList.append foo
+ /></code>). (Also, if you use
+ <code class="inline-code">BeansWrapper</code> and configure it so it exposes
+ the public methods, you can use the Java API for variables
+ that are for <code class="inline-code">java.util.Map</code>-s and
+ <code class="inline-code">java.util.List-s</code>. Just like with Apache
+ Velocity.)</p>
+ </li>
+ </ul>
+
+ <p>But beware, these solutions have a problem: The <a href="dgui_template_exp.html#dgui_template_exp_sequenceop_cat">sequence
+ concatenation</a>, <a href="dgui_template_exp.html#dgui_template_exp_seqenceop_slice">sequence slice</a>
+ operator (like <code class="inline-code">seq[5..10]</code>) and
+ <code class="inline-code">?reverse</code> do not copy the original sequence,
+ just wraps it (for efficiency), so the resulting sequence will
+ change if the original sequence is changed later (an abnormal
+ aliasing effect). The same problem exists with the result of <a href="dgui_template_exp.html#dgui_template_exp_hashop_cat">hash concatenation</a>;
+ it just wraps the two hashes, so the resulting hash will magically
+ change if you modify the hashes you have added earlier. As a
+ work-around, after you did the above problematic operations,
+ either be sure you will not modify the objects that were used as
+ input, or create a copy of the result with a method provided by
+ the solution described in above two points (e.g. in FMPP you could
+ do <code class="inline-code"><#assign b =
+ pp.newWritableSequence(a[5..10])></code> and
+ <code class="inline-code"><#assign c = pp.newWritableHash(hashA +
+ hashB)></code>). Of course this is easy to miss... so again,
+ rather try to build the data-model so you will not need to modify
+ collections, or use a presentation task helper class as was shown
+ earlier.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_null">
+ 17.
+ What about <code class="inline-code">null</code> and the FreeMarker
+ template language?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>The FreeMarker template language doesn't know the Java
+ language <code class="inline-code">null</code> at all. It doesn't have
+ <code class="inline-code">null</code> keyword, and it can't test if something is
+ <code class="inline-code">null</code> or not. When it technically faces with a
+ <code class="inline-code">null</code>, it treats it exactly as a missing
+ variable. For example, both if <code class="inline-code">x</code> is
+ <code class="inline-code">null</code> in the data-model and if it's not present
+ at all, <code class="inline-code">${x!'missing'}</code> will print ``missing'',
+ you can't tell the difference. Also, if for example you want to
+ test if a Java method has returned <code class="inline-code">null</code>, just
+ write something like <code class="inline-code"><#if
+ foo.bar()??></code>.</p>
+
+ <p>You may interested in the rationale behind this. From the
+ viewpoint of the presentation layer a <code class="inline-code">null</code> and
+ non-existent thing is almost always the same. The difference
+ between this two is usually just a technical detail, which is
+ rather the result of implementation details than of the
+ application logic. That you can't compare something to
+ <code class="inline-code">null</code> (unlike in Java); it doesn't make sense to
+ compare something with <code class="inline-code">null</code> in a template,
+ since the template language doesn't do identity comparison (like
+ the Java <code class="inline-code">==</code> operator when you compare two
+ objects) but the more common sense value comparison (like Java's
+ <code class="inline-code">Object.equals(Object)</code>; that doesn't work with
+ <code class="inline-code">null</code> either). And how could FreeMarker tell if
+ something concrete equals with something that is missing and thus
+ unknown? Or if two missing (unknown) things are equal? Of course
+ these questions can't be answered.</p>
+
+ <p>There is at least one problem with this
+ <code class="inline-code">null</code>-unaware approach. When you call a Java
+ method from a template, you may want to pass a
+ <code class="inline-code">null</code> value as argument (since the method was
+ designed to be used in Java language, where the concept of
+ <code class="inline-code">null</code> is known). In this case you can exploit a
+ bug of FreeMarker (that we will not fix until we provide a correct
+ solution for passing <code class="inline-code">null</code> values to a method):
+ if you specify a missing variable as the argument, then it will
+ not cause an error, but a <code class="inline-code">null</code> will be passed
+ to the method instead. Like <code class="inline-code">foo.bar(nullArg)</code>
+ will call the <code class="inline-code">bar</code> method with
+ <code class="inline-code">null</code> as argument, assuming that there is no
+ varaible exists with ``nullArg'' name.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 18.
+ How can I use the output of a directive (macro) in
+ expressions (as a parameter to another directive)?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>Capture the output into a variable with the
+ <code class="inline-code">assign</code> or <code class="inline-code">local</code> directive.
+ For example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign capturedOutput><@outputSomething /></#assign>
+<@otherDirective someParam=capturedOutput /></pre></div>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 19.
+ Why do I have ``?''-s in the output instead of character
+ <em>X</em>?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>This is because the character that you want to print can't
+ be represented with the <a href="gloss.html#gloss.charset">charset</a> (encoding) used for the
+ output stream, so the Java platform (not FreeMarker) substitutes
+ the problematic character with question mark. In general you
+ should use the same charset for the output as for the template
+ (use the <code class="inline-code">getEncoding()</code> method of the template
+ object), or which is even safer, you should always use UTF-8
+ charset for the output. The charset used for the output stream is
+ not decided by FreeMarker, but by you, when you create the
+ <code class="inline-code">Writer</code> that you pass to the
+ <code class="inline-code">process</code> method of the template.</p>
+
+ <p>Example: Here I use UTF-8 charset in a servlet:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">...
+resp.setContentType("text/html; charset=utf-8");
+Writer out = resp.getWriter();
+...
+t.process(root, out);
+...</pre></div>
+
+ <p>Note that the question marks (or other substitution
+ characters) may be produced outside FreeMarker, in which case the
+ above obviously will not help. For example a bad/missconfigured
+ database connection or JDBC driver may bring the text already with
+ substitution characters in it. HTML forms are another potential
+ source of encoding problems. It's a good idea to print the
+ numerical code of the characters of the string on various places,
+ to see where the problem occurs first.</p>
+
+ <p>You can read more about charsets and FreeMarker <a href="pgui_misc_charset.html">here...</a></p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 20.
+ How to retrieve values calculated in templates after
+ template execution done?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>First of all, be sure your application is designed well:
+ templates should display data, and almost never calculate data. If
+ you are still sure you want to do it, read on...</p>
+
+ <p>When you use <code class="inline-code"><#assign x = "foo"></code>,
+ then you do not actually modify the data-model (since that is
+ read-only, see: <a href="pgui_misc_multithreading.html">Programmer's Guide/Miscellaneous/Multithreading</a>), but
+ create the <code class="inline-code">x</code> variable in the runtime <a href="gloss.html#gloss.environment">environment</a> of the processing
+ (see <a href="pgui_misc_var.html">Programmer's Guide/Miscellaneous/Variables</a>). The problem is that this
+ runtime environment will be discarded when
+ <code class="inline-code">Template.process</code> returns, as it was created for
+ a single <code class="inline-code">Template.process</code> call:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">// internally an Environment will be created, and then discarded
+myTemplate.process(root, out);</pre></div>
+
+ <p>To prevent this, you can do the below, which is equivalent
+ with the above, except that you have chance to return the
+ variables created in the template:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-unspecified">Environment env = myTemplate.createProcessingEnvironment(root, out);
+env.process(); // process the template
+TemplateModel x = env.getVariable("x"); // get variable x</pre></div>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="faq_implement_function_or_macro_in_java">
+ 21.
+ How to implement a function or macro in Java Language
+ instead of in the template language?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>It's not possible (yet), but something very similar is
+ possible if you write a class that implements
+ <code class="inline-code">freemarker.template.TemplateMethodModelEx</code> or
+ <code class="inline-code">freemarker.template.TemplateDirectiveModel</code>
+ respectively, and then where you were write <code class="inline-code"><#function
+ my
+ <em class="code-color">...</em>><em class="code-color">...</em></#function></code>
+ or <code class="inline-code"><#macro my
+ <em class="code-color">...</em>><em class="code-color">...</em></#macro></code>
+ you write <code class="inline-code"><#assign my = "your.package.YourClass
+ "?</code><a href="ref_builtins_expert.html#ref_builtin_new"><code>new</code></a><code class="inline-code">()></code>
+ instead. Note that using the <code class="inline-code">assign</code> directive
+ for this works because functions (and methods) and macros are just
+ plain variables in FreeMarker. (For the same reason you could also
+ put <code class="inline-code">TemplateMethodModelEx</code> or
+ <code class="inline-code">TemplateDirectiveModel</code> instances into the
+ data-model before calling the template, or into the shared
+ variable map (see:
+ <code class="inline-code">freemarker.template.Configuration.setSharedVariable(String,
+ TemplateModel)</code>) when you initialize the
+ application.)</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 22.
+ Why is FreeMarker logging suppressed for my
+ application?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>It is because FreeMarker does not find any logging system.
+ To fix this, you must make available one of the following logging
+ systems for your application: Avalon
+ (<code class="inline-code">org.apache.log</code>), Log4J
+ (<code class="inline-code">org.apache.log4j</code>), or use J2SE 1.4 or later
+ (that contains <code class="inline-code">java.util.logging</code>). That is, the
+ class-loader used with your application must find one of the
+ mentioned classes.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 23.
+ <a name="misc.faq.niceErrorPage"></a> In my Servlet
+ based application, how do I show a nice error page instead of a
+ stack trace when error occurs during template processing?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>First of all, use <code class="inline-code">RETHROW_HANDLER</code> instead
+ of the default <code class="inline-code">DEBUG_HANDLER</code> (for more
+ information about template exception handlers <a href="pgui_config_errorhandling.html">read this...</a>). Now
+ FreeMarker will not print anything to the output when an error
+ occurs, so the control is in your hands. After you have caught the
+ exception of
+ <code class="inline-code">Template.process(<em class="code-color">...</em>)</code>
+ basically you can follow two strategies:</p>
+
+ <ul>
+ <li>
+ <p>Call <code class="inline-code">httpResp.isCommitted()</code>, and if
+ that returns <code class="inline-code">false</code>, then you call
+ <code class="inline-code">httpResp.reset()</code> and print a ``nice error
+ page'' for the visitor. If the return value was
+ <code class="inline-code">true</code>, then try to finish the page be
+ printing something that makes clear for the visitor that the
+ page generation was abruptly interrupted because of an error
+ on the Web server. You may have to print a lot of redundant
+ HTML end-tags and set colors and font size to ensure that the
+ error message will be actually readable in the browser window
+ (check the source code of the
+ <code class="inline-code">HTML_DEBUG_HANDLER</code> in
+ <code class="inline-code">src\freemarker\template\TemplateException.java</code>
+ to see an example).</p>
+ </li>
+
+ <li>
+ <p>Use full page buffering. This means that the
+ <code class="inline-code">Writer</code> doesn't send the output to the
+ client progressively, but buffers the whole page in the
+ memory. Since you provide the <code class="inline-code">Writer</code>
+ instance for the
+ <code class="inline-code">Template.process(<em class="code-color">...</em>)</code>
+ method, this is your responsibility, FreeMarker has nothing to
+ do with it. For example, you may use a
+ <code class="inline-code">StringWriter</code>, and if
+ <code class="inline-code">Template.process(<em class="code-color">...</em>)</code>
+ returns by throwing an exception, then ignore the content
+ accumulated by the <code class="inline-code">StringWriter</code>, and send
+ an error page instead, otherwise you print the content of
+ <code class="inline-code">StringWriter</code> to the output. With this
+ method you surely don't have to deal with partially sent
+ pages, but it can have negative performance implications
+ depending on the characteristic of the pages (for example, the
+ user will experience more response delay for a long page that
+ is generated slowly, also the server will consume more RAM).
+ Note that using a <code class="inline-code">StringWriter</code> is surely
+ not the most efficient solution, as it often reallocates its
+ buffer as the accumulated content grows.</p>
+ </li>
+ </ul>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 24.
+ I'm using a visual HTML editor that mangles template tags.
+ Will you change the template language syntax to accommodate my
+ editor?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>We won't change the standard version, because a lot of
+ templates depend on it.</p>
+
+ <p>Our view is that the editors that break template code are
+ themselves broken. A good editor should ignore, not mangle, what
+ it doesn't understand.</p>
+
+ <p>You maybe interested in that starting from FreeMarker 2.3.4
+ you can use <code class="inline-code">[</code> and <code class="inline-code">]</code> instead
+ of <code class="inline-code"><</code> and <code class="inline-code">></code>. For more
+ details <a href="dgui_misc_alternativesyntax.html">read
+ this...</a></p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 25.
+ How fast is FreeMarker? Is it true that 2.x is slower than
+ 1.x (FreeMarker classic)?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>First of all, don't forget that FreeMarker is only the view
+ rendering component in an <a href="gloss.html#gloss.MVC">MVC</a>
+ system. Furthermore MVC templates tend to be simple: many static
+ text with a few interpolations and loops and conditional block. So
+ it is not like PHP or Model 1 JSP; your application performance is
+ not affected that much by the execution time of templates.</p>
+
+ <p>FreeMarker is certainly fast enough that it will only very
+ rarely be a bottleneck in your application. Rather, other factors
+ such as the speed of the data-base operations or network bandwidth
+ will likely dominate. The impact of FreeMarker performance could
+ be noticeable only for really busy sites (say, over 30 hits per
+ second per server), where almost all database data is cached. If
+ you are finding FreeMarker slow, do make sure that the cache of
+ parsed templates works well
+ (<code class="inline-code">Configuration.getTemplate</code> be default uses
+ caching). Parsing a template file is a relatively costly step; in
+ most long-running server-side applications, you will want to parse
+ a template once and have it be used many times. (Note that
+ FreeMarker 2.1.4 and earlier versions have bugs that sometimes can
+ ruin caching.)</p>
+
+ <p>FreeMarker 2.1 is slower than 1.7.1. This surely depends on
+ your templates, but it could be slower by a factor of 2 or 3. But
+ again, it does not means that response time will be 2 or 3 times
+ slower; most FreeMarker user simply should not be able to perceive
+ the change in the final response time.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 26.
+ How can my Java classes ask a template for information about
+ its structure (e.g. a list of all the variables)?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>In FreeMarker 2.2, <code class="inline-code">Template</code> has an
+ undocumented method for examining the parsed template:
+ <code class="inline-code">getRootTreeNode</code>.</p>
+
+ <p>But listing all accessed variables is not possible, because
+ variable names can be dynamically generated from data. However,
+ there's a more important reason why FreeMarker doesn't support
+ this. The design of FreeMarker is based on the idea of a
+ separation between business objects and presentation objects. This
+ separation takes two forms:</p>
+
+ <div class="orderedlist"><ol type="1">
+ <li>
+ <p>The templates know what data to expect, but they don't
+ know how it's generated.</p>
+ </li>
+
+ <li>
+ <p>The business objects know what data to produce, but they
+ don't know how it's going to be displayed. Therefore, they
+ don't know anything about templates.</p>
+ </li>
+ </ol></div>
+
+ <p>Since the business objects don't rely on the templates, if
+ you need to use them with some other presentation system, you
+ won't have to rewrite your application.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 27.
+ Will you ever provide backward compatibility?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>FreeMarker 2.0 was a complete rewrite of FreeMarker 1.x, by
+ a new author. The 1.x series continues as separated project:
+ FreeMarker Classic. Since 2.x follows different philosophy than
+ 1.x, 2.0x releases were immature despite the high major version
+ number. This caused further radical changes between 2.01 and 2.1.
+ As of 2.1 things were much more matured, and 2.2 is almost
+ backward compatible with 2.1. We hope that this tendency
+ continues.</p>
+
+ <p>Currently, the rule is that releases with different second
+ version number (as 2.1.x and 2.2.x) are not (fully) compatible.
+ Releases where only the third version number differs (as 2.2.1 and
+ 2.2.6) are compatible.</p>
+
+ <p>We always provide backward compatible bugfix releases for
+ the released versions. So basically, you don't
+ <em>have</em> to switch to a new, non-backward
+ compatible release in an already written product. It's a something
+ for something situation... FreeMarker recovers faster from design
+ mistakes than many other projects, but the price of this is that
+ major releases are not backward compatible. This is admittedly not
+ optimal, it would be better if there are fewer design mistakes...
+ but, well, it is the reality.</p>
+ </dd>
+
+
+
+
+
+ <dt class="question" id="">
+ 28.
+ If we distribute FreeMarker with our product, do we have to
+ release the source code for our product?
+
+ </dt>
+
+
+ <dd class="answer">
+
+ <p>No. As of 2.0, FreeMarker is released under a BSD-style
+ license. This means that source or binary distributions may be
+ made freely, and can be included in other products, whether
+ commercial or open source.</p>
+
+ <p>The only restrictions apply to the copyright of FreeMarker
+ itself, and the use of FreeMarker or its contributors as
+ endorsements of your own product. See the <a href="app_license.html">LICENSE</a> for further details.</p>
+
+ <p>If you use FreeMarker, we hope you'll send us a link to some
+ information about your product, but that's optional as
+ well.</p>
+ </dd>
+
+
+ </dl>
+
+ </div>
+<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="app.html"><span>Previous</span></a><a class="paging-arrow next" href="app_install.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app_install.html b/legacy-tests/build/test/1/app_install.html
new file mode 100644
index 0000000..6125c22
--- /dev/null
+++ b/legacy-tests/build/test/1/app_install.html
@@ -0,0 +1,99 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-appendix">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Installing FreeMarker - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Installing FreeMarker">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app_install.html">
+<link rel="canonical" href="http://example.com/app_install.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes","Installing FreeMarker"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="app_faq.html"><span>Previous</span></a><a class="paging-arrow next" href="app_build.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="app_install" itemprop="headline">Installing FreeMarker</h1>
+</div></div><p>No real installation needed. Simply copy
+ <code class="inline-code">lib/freemarker.jar</code> to a location where your Java
+ application's class-loader will find it. For example, if you use
+ FreeMarker in a web application, you probably want to put
+ <code class="inline-code">freemarker.jar</code> into the
+ <code class="inline-code">WEB-INF/lib</code> directory of your web application.</p><p>No real installation needed. Simply copy
+ <code class="inline-code">lib/freemarker.jar</code> to a location where your Java
+ application's ClassLoader will find it. For example, if you use
+ FreeMarker in a web application, you probably want to put
+ <code class="inline-code">freemarker.jar</code> into the
+ <code class="inline-code">WEB-INF/lib</code> directory of your web application. (If
+ you want to use FreeMarker with JSP Model-2 style (which also means that
+ you can use custom JSP taglibs in the templates), some extra steps
+ needed. For more information please see <a href="pgui_misc_servlet.html">the chapter about servlets</a>.)</p><p>However, some third party libraries have also be available for the
+ class-loader, if you want to enable certain
+ <em>optional</em> FreeMarker features:</p><ul>
+ <li>
+ <p>At least J2SE 1.4 is required for regular expression
+ built-ins.</p>
+ </li>
+
+ <li>
+ <p>At least J2SE 1.4 or a JAXP + DOM implementation + SAX
+ implementation is needed for the XML wrapping.</p>
+ </li>
+
+ <li>
+ <p>Jaxen (recommended, <a href="http://jaxen.org/">download here</a>) or Apache Xalan
+ is needed for XML XPath support. Please use at least Jaxen
+ 1.1-beta-8, not older versions! Apache Xalan classes are included in
+ Sun J2SE 1.4, 1.5 and 1.6 (and maybe later too), so no separate
+ Xalan jar is needed with those versions.</p>
+ </li>
+
+ <li>
+ <p>Obviously, <code class="inline-code">javax.servlet</code> classes are needed
+ for <code class="inline-code">FreemarkerServlet</code>. Servlet version 2.2 or
+ later is needed.</p>
+ </li>
+
+ <li>
+ <p>For the custom JSP taglib support, you will need JSP 1.2 API
+ classes. No JSP implementation needed, just the API. For more
+ information please see <a href="pgui_misc_servlet.html">the chapter
+ about servlets</a>.</p>
+ </li>
+
+ <li>
+ <p>Obviously, Jython classes are needed for the Jython
+ wrapper.</p>
+ </li>
+
+ <li>
+ <p>JDOM is needed for the deprecated freemarker.ext.jdom
+ package.</p>
+ </li>
+ </ul><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="app_faq.html"><span>Previous</span></a><a class="paging-arrow next" href="app_build.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app_license.html b/legacy-tests/build/test/1/app_license.html
new file mode 100644
index 0000000..f8f719d
--- /dev/null
+++ b/legacy-tests/build/test/1/app_license.html
@@ -0,0 +1,92 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-appendix">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>License - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="License">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app_license.html">
+<link rel="canonical" href="http://example.com/app_license.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes","License"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_0RC1.html"><span>Previous</span></a><a class="paging-arrow next" href="gloss.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="app_license" itemprop="headline">License</h1>
+</div></div><p>FreeMarker 1.x was released under the LGPL license. Later, by
+ community consensus, we have switched over to a BSD-style license. As of
+ FreeMarker 2.2pre1, the original author, <em>Benjamin
+ Geer</em>, has relinquished the copyright in behalf of Visigoth
+ Software Society. The current copyright holder is the Visigoth Software
+ Society.</p><p> </p><p>Copyright (c) 2003 The Visigoth Software Society. All rights
+ reserved.</p><p>Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:</p><div class="orderedlist"><ol type="1">
+ <li>
+ <p>Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.</p>
+ </li>
+
+ <li>
+ <p>The end-user documentation included with the redistribution,
+ if any, must include the following acknowledgement: <em>"This
+ product includes software developed by the Visigoth Software Society
+ (http://www.visigoths.org/)."</em> Alternately, this
+ acknowledgement may appear in the software itself, if and wherever
+ such third-party acknowledgements normally appear.</p>
+ </li>
+
+ <li>
+ <p>Neither the name "FreeMarker", "Visigoth", nor any of the
+ names of the project contributors may be used to endorse or promote
+ products derived from this software without prior written
+ permission. For written permission, please contact
+ visigoths@visigoths.org.</p>
+ </li>
+
+ <li>
+ <p>Products derived from this software may not be called
+ "FreeMarker" or "Visigoth" nor may "FreeMarker" or "Visigoth" appear
+ in their names without prior written permission of the Visigoth
+ Software Society.</p>
+ </li>
+ </ol></div><p>THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ THE POSSIBILITY OF SUCH DAMAGE.</p><p> </p><p>This software consists of voluntary contributions made by many
+ individuals on behalf of the Visigoth Software Society. For more
+ information on the Visigoth Software Society, please see <a href="http://www.visigoths.org/">http://www.visigoths.org/</a></p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_0RC1.html"><span>Previous</span></a><a class="paging-arrow next" href="gloss.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/app_versions.html b/legacy-tests/build/test/1/app_versions.html
new file mode 100644
index 0000000..a63298e
--- /dev/null
+++ b/legacy-tests/build/test/1/app_versions.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-appendix">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Versions - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Versions">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/app_versions.html">
+<link rel="canonical" href="http://example.com/app_versions.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Appendixes","Versions"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="app_build.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3_16.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="app_versions" itemprop="headline">Versions</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="versions_2_3_16.html" data-menu-target="versions_2_3_16">2.3.16</a></li><li><a class="page-menu-link" href="versions_2_3_15.html" data-menu-target="versions_2_3_15">2.3.15</a></li><li><a class="page-menu-link" href="versions_2_3_14.html" data-menu-target="versions_2_3_14">2.3.14</a></li><li><a class="page-menu-link" href="versions_2_3_13.html" data-menu-target="versions_2_3_13">2.3.13</a></li><li><a class="page-menu-link" href="versions_2_3_12.html [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/src/test/1/bat.jpg b/legacy-tests/build/test/1/bat.jpg
similarity index 100%
copy from src/test/1/bat.jpg
copy to legacy-tests/build/test/1/bat.jpg
diff --git a/legacy-tests/build/test/1/detailed-toc.html b/legacy-tests/build/test/1/detailed-toc.html
new file mode 100644
index 0000000..f375b25
--- /dev/null
+++ b/legacy-tests/build/test/1/detailed-toc.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-docgen-detailed-toc">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="FreeMarker Manual">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/index.html">
+<link rel="canonical" href="http://example.com/index.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><span itemprop="name">Table of Contents</span></li></ul><div class="bookmarks" title="Book [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = [];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><span class="paging-arrow disabled previous"><span>Previous</span></span><a class="paging-arrow next" href="preface.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-book" id="autoid_1" itemprop="headline">FreeMarker Manual <span class="subtitle">For FreeMarker 2.3.16</span>
+</h1>
+</div></div><div class="page-menu">
+<ul><li><a class="page-menu-link" href="preface.html" data-menu-target="preface">Preface</a><ul><li><a class="page-menu-link" href="preface.html#autoid_2" data-menu-target="autoid_2">What is FreeMarker?</a></li><li><a class="page-menu-link" href="preface.html#autoid_3" data-menu-target="autoid_3">What should I read?</a></li><li><a class="page-menu-link" href="preface.html#autoid_4" data-menu-target="autoid_4">Document conventions</a></li><li><a class="page-menu-link" href="preface.html#a [...]
+resources</a></li><li><a class="page-menu-link" href="pgui_misc_servlet.html#autoid_55" data-menu-target="autoid_55">Using JSP custom tags in FTL</a></li><li><a class="page-menu-link" href="pgui_misc_servlet.html#autoid_56" data-menu-target="autoid_56">Embed FTL into JSP pages</a></li></ul></li><li><a class="page-menu-link" href="pgui_misc_secureenv.html" data-menu-target="pgui_misc_secureenv">Configuring security policy for FreeMarker</a></li><li><a class="page-menu-link" href="pgui_mis [...]
+release</a></li></ul></li></ul></li><li><a class="page-menu-link" href="versions_2_3.html" data-menu-target="versions_2_3">2.3</a><ul><li><a class="page-menu-link" href="versions_2_3.html#autoid_168" data-menu-target="autoid_168">Non backward-compatible changes!</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_169" data-menu-target="autoid_169">Changes on the FTL side</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_170" data-menu-target="autoid_17 [...]
+4</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_174" data-menu-target="autoid_174">Differences between the Release Candidate 4 and Release
+Candidate 3</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_175" data-menu-target="autoid_175">Differences between the Release Candidate 3 and Release
+Candidate 2</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_176" data-menu-target="autoid_176">Differences between the Release Candidate 2 and Release
+Candidate 1</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_177" data-menu-target="autoid_177">Differences between the Release Candidate 1 and Preview 16
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_178" data-menu-target="autoid_178">Differences between the Preview 16 and Preview 15
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_179" data-menu-target="autoid_179">Differences between the Preview 15 and Preview 14
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_180" data-menu-target="autoid_180">Differences between the Preview 14 and Preview 13
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_181" data-menu-target="autoid_181">Differences between the Preview 13 and Preview 12
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_182" data-menu-target="autoid_182">Differences between the Preview 12 and Preview 11
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_183" data-menu-target="autoid_183">Differences between the Preview 11 and Preview 10
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_184" data-menu-target="autoid_184">Differences between the Preview 10 and Preview 9
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_185" data-menu-target="autoid_185">Differences between the Preview 9 and Preview 8
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_186" data-menu-target="autoid_186">Differences between the Preview 8 and Preview 7
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_187" data-menu-target="autoid_187">Differences between the Preview 7 and Preview 6
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_188" data-menu-target="autoid_188">Differences between the Preview 6 and Preview 5
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_189" data-menu-target="autoid_189">Differences between the Preview 5 and Preview 4
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_190" data-menu-target="autoid_190">Differences between the Preview 4 and Preview 3
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_191" data-menu-target="autoid_191">Differences between the Preview 3 and Preview 2
+releases</a></li><li><a class="page-menu-link" href="versions_2_3.html#autoid_192" data-menu-target="autoid_192">Differences between the Preview 2 and Preview 1
+releases</a></li></ul></li></ul></li><li><a class="page-menu-link" href="versions_2_2_8.html" data-menu-target="versions_2_2_8">2.2.8</a><ul><li><a class="page-menu-link" href="versions_2_2_8.html#autoid_193" data-menu-target="autoid_193">Changes on the FTL side</a></li><li><a class="page-menu-link" href="versions_2_2_8.html#autoid_194" data-menu-target="autoid_194">Changes on the Java side</a></li><li><a class="page-menu-link" href="versions_2_2_8.html#autoid_195" data-menu-target="auto [...]
+releases</a></li></ul></li></ul></li><li><a class="page-menu-link" href="versions_2_1_5.html" data-menu-target="versions_2_1_5">2.1.5</a><ul><li><a class="page-menu-link" href="versions_2_1_5.html#autoid_217" data-menu-target="autoid_217">Changes on the Java side</a></li></ul></li><li><a class="page-menu-link" href="versions_2_1_4.html" data-menu-target="versions_2_1_4">2.1.4</a><ul><li><a class="page-menu-link" href="versions_2_1_4.html#autoid_218" data-menu-target="autoid_218">Changes [...]
+boolean, as well as numerical ranges.</a></li><li><a class="page-menu-link" href="versions_2_0RC1.html#autoid_239" data-menu-target="autoid_239">API Changes</a></li><li><a class="page-menu-link" href="versions_2_0RC1.html#autoid_240" data-menu-target="autoid_240">Syntactical Miscellany</a></li></ul></li></ul></li><li><a class="page-menu-link" href="app_license.html" data-menu-target="app_license">License</a></li></ul></li><li><a class="page-menu-link" href="gloss.html" data-menu-target=" [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui.html b/legacy-tests/build/test/1/dgui.html
new file mode 100644
index 0000000..03ccd6e
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-part">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Template Author's Guide - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Template Author's Guide">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui.html">
+<link rel="canonical" href="http://example.com/dgui.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="preface.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-part" id="dgui" itemprop="headline">Template Author's Guide</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="dgui_quickstart.html" data-menu-target="dgui_quickstart">Getting Started</a><ul><li><a class="page-menu-link" href="dgui_quickstart_basics.html" data-menu-target="dgui_quickstart_basics">Template + data-model = output</a></li><li><a class="page-menu-link" href="dgui_quickstart_datamodel.html" data-menu-target="dgui_quickstart_datamodel">The data-model at a glance</a></li><li><a class="page-menu-link" href="dgui_quickstart_template.html" data-menu-t [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_datamodel.html b/legacy-tests/build/test/1/dgui_datamodel.html
new file mode 100644
index 0000000..4edb5f1
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_datamodel.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-chapter">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Values, Types - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Values, Types">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_datamodel.html">
+<link rel="canonical" href="http://example.com/dgui_datamodel.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Values, Types"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_quickstart_template.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel_basics.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="dgui_datamodel" itemprop="headline">Values, Types</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="dgui_datamodel_basics.html" data-menu-target="dgui_datamodel_basics">Basics</a></li><li><a class="page-menu-link" href="dgui_datamodel_types.html" data-menu-target="dgui_datamodel_types">The types</a></li></ul> </div><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_quickstart_template.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel_basics.html"><span>Next</spa [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_datamodel_basics.html b/legacy-tests/build/test/1/dgui_datamodel_basics.html
new file mode 100644
index 0000000..e68a283
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_datamodel_basics.html
@@ -0,0 +1,221 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Basics - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Basics">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_datamodel_basics.html">
+<link rel="canonical" href="http://example.com/dgui_datamodel_basics.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Values, Types","Basics"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_datamodel.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel_types.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_datamodel_basics" itemprop="headline">Basics</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#topic.value" data-menu-target="topic.value">What is a value?</a></li><li><a class="page-menu-link" href="#autoid_13" data-menu-target="autoid_13">What is type?</a></li><li><a class="page-menu-link" href="#autoid_14" data-menu-target="autoid_14">The data-model is a hash</a></li></ul> </div> <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>It is assumed that you have already read the <a href="dgui_quickstart.html">Getting Started</a> chapter.</p>
+ </div>
+<p>Understanding the concept of values and types is crucial for the
+ understanding of data-models. However, the concept of values and types
+ is not confined to data-models, as you will see.</p>
+
+
+
+
+<h2 class="content-header header-section2" id="topic.value">What is a value?</h2>
+
+
+
+
+ <p><span class="marked-for-programmers">Real programmers can safely skip
+ this section.</span></p>
+
+ <p>Examples of <em>values</em> as you know the term
+ from the everyday math are 16, 0.5, and so on, i.e. numbers. In the
+ case of computer languages the value term has a wider meaning, as a
+ value needn't be a number. For example, take this data-model:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-data-model"><a name="example.stdDataModel"></a>(root)
+ |
+ +- user = "Big Joe"
+ |
+ +- today = Jul 6, 2007
+ |
+ +- todayHoliday = false
+ |
+ +- lotteryNumbers
+ | |
+ | +- (1st) = 20
+ | |
+ | +- (2st) = 14
+ | |
+ | +- (3rd) = 42
+ | |
+ | +- (4th) = 8
+ | |
+ | +- (5th) = 15
+ |
+ +- cargo
+ |
+ +- name = "coal"
+ |
+ +- weight = 40</pre></div>
+
+ <p>We say that the <em>value</em> of the the
+ <code class="inline-code">user</code> variable is "Big Joe" (a string), the
+ <em>value</em> of <code class="inline-code">today</code> is Jul 6,
+ 2007 (a date), the <em>value</em> of
+ <code class="inline-code">todayHoliday</code> is false (a boolean, ie. a yes/no
+ thing). The <em>value</em> of
+ <code class="inline-code">lotteryNumbers</code> is the sequence that contains 20,
+ 14, 42, 8, 15. Surely <code class="inline-code">lotteryNumbers</code> is multiple
+ values in the sense that it <em>contains</em> multiple
+ values (for example, the 2nd item in it is a the
+ <em>value</em> 14), but still,
+ <code class="inline-code">lotteryNumbers</code> itself is a single value. It's
+ like a box that contains many other items; the whole box can be seen
+ as a single item. Last not least we also have the
+ <em>value</em> of <code class="inline-code">cargo</code>, which is a
+ hash (a box-like thing again).So, a value is something that can be
+ stored in a variable (e.g., in <code class="inline-code">user</code> or
+ <code class="inline-code">cargo</code> or <code class="inline-code">cargo.name</code>). But a
+ value need not be stored in a variable to be called a value, for
+ example we have the value 100 here:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if cargo.weight < <strong>100</strong>>Light cargo</#if></pre></div>
+
+ <p>Or the temporaly result of a calculations are also called
+ values, like 20 and 120 when this template is executed (it will
+ print 120):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${cargo.weight / 2 + 100}</pre></div>
+
+ <p>Explanation for this last: As the result of dividing the two
+ values, 40 (the weight of the cargo) and 2, a new value 20 is
+ created. Then 100 is addted to it, so the value 120 is created. Then
+ 120 is printed
+ (<code class="inline-code">${<em class="code-color">...</em>}</code>), and the
+ template execution goes on and all these values gone.</p>
+
+ <p>Certainly now you feel what the value term means.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_13">What is type?</h2>
+
+
+ <p>Values have an important aspect, their type. For example the
+ type of the value of the <code class="inline-code">user</code> variable is string,
+ and the type of the value of the <code class="inline-code">lotteryNumbers</code>
+ variable is sequence. The type of a value is important because it
+ determines to a large extent how and where you can use the value.
+ Like <code class="inline-code">${user / 2}</code> is an error, but
+ <code class="inline-code">${cargo.weight / 2}</code> works and prints 20, since
+ division only does make sense for a number, but not for a string.
+ Or, using dot like in <code class="inline-code">cargo.name</code> does make sense
+ only if <code class="inline-code">cargo</code> is a hash. Or, you can list with
+ <code class="inline-code"><#list <em class="code-color">...</em>></code>
+ sequences only. Or, the condition of <code class="inline-code"><#if
+ ...></code> must be a boolean. And so on.</p>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>A little terminology... Saying "a boolean" or "a boolean
+ value" or "a value of type boolean" are all the same.</p>
+ </div>
+
+
+ <p><a name="topic.multitype"></a>A value can have multiple types at the same time,
+ although it's rarely utilized. For example in the data-model below
+ <code class="inline-code">mouse</code> is both a string and a hash:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-data-model">(root)
+ |
+ +- mouse = "Yerri"
+ |
+ +- age = 12
+ |
+ +- color = "brown"</pre></div>
+
+ <p>If you merge this template with the above data-model:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${mouse} <#-- uses mouse as a string -->
+${mouse.age} <#-- uses mouse as a hash -->
+${mouse.color} <#-- uses mouse as a hash --></pre></div>
+
+ <p>the output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">Yerri
+12
+brown</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_14">The data-model is a hash</h2>
+
+
+ <p>Looking at the various data-model examples you may already
+ realized: the thing marked as "(root)" is just a value of type hash.
+ When you write something like <code class="inline-code">user</code>, that means
+ that you want the "user" variable stored in the root hash. Like if
+ you were writing <code class="inline-code">root.user</code>, except that there is
+ no variable called "root" so that wouldn't work.</p>
+
+ <p>Some may get confused by the fact that our example data-model,
+ that is, the root hash, contains further hashes and sequences
+ (<code class="inline-code">lotteryNumbers</code> and <code class="inline-code">cargo</code>).
+ There is nothing special in that. A hash contains other variables,
+ and those variables have a value, which can be a string, a number,
+ etc., and of course it can be a hash or sequence as well. Because,
+ as it was explained earlier, a sequence or a hash is just a value,
+ like a string or a number is.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_datamodel.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel_types.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_datamodel_types.html b/legacy-tests/build/test/1/dgui_datamodel_types.html
new file mode 100644
index 0000000..aea1348
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_datamodel_types.html
@@ -0,0 +1,458 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>The types - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="The types">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_datamodel_types.html">
+<link rel="canonical" href="http://example.com/dgui_datamodel_types.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Values, Types","The types"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_datamodel_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_datamodel_types" itemprop="headline">The types</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#dgui_datamodel_scalar" data-menu-target="dgui_datamodel_scalar">Scalars</a></li><li><a class="page-menu-link" href="#dgui_datamodel_container" data-menu-target="dgui_datamodel_container">Containers</a></li><li><a class="page-menu-link" href="#autoid_15" data-menu-target="autoid_15">Subroutines</a><ul><li><a class="page-menu-link" href="#dgui_datamodel_method" data-menu-target="dgui_datamodel_method">Methods and functions</a></li><li><a class="page [...]
+ <li>
+ <a href="#dgui_datamodel_scalar">Scalars:</a>
+
+ <ul>
+ <li>
+ String
+ </li>
+
+ <li>
+ Number
+ </li>
+
+ <li>
+ Boolean
+ </li>
+
+ <li>
+ Date
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_datamodel_container">Containers:</a>
+
+ <ul>
+ <li>
+ Hash
+ </li>
+
+ <li>
+ Sequence
+ </li>
+
+ <li>
+ Collection
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ Subroutines:
+
+ <ul>
+ <li>
+ <a href="#dgui_datamodel_method">Methods and
+ functions</a>
+ </li>
+
+ <li>
+ <a href="#dgui_datamodel_userdefdir">User-defined
+ directives</a>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ Miscellaneous/seldom used:
+
+ <ul>
+ <li>
+ <a href="#dgui_datamodel_node">Node</a>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_datamodel_scalar">Scalars</h2>
+
+
+ <a name="topic.designer.scalarVariable"></a>
+
+ <p>These are the basic, simple kind of values. They can
+ be:</p>
+
+ <ul>
+ <li>
+ <p>String: It is simple text, e.g., the name of a
+ product.</p>
+
+ <p>If you want to give a string value directly in the
+ template, rather than use a variable that comes from the data
+ model, you write the text between quotation marks, e.g.,
+ <code class="inline-code">"green mouse"</code> or <code class="inline-code">'green
+ mouse'</code>. (More details regarding the syntax can be
+ found <a href="dgui_template_exp.html#dgui_template_exp_direct_string">later</a>.)</p>
+ </li>
+
+ <li>
+ <p>Number: For example the price of a product.
+ <span class="marked-for-programmers">Whole numbers and non-whole
+ numbers are not distinguished; there is only a single number
+ type. So for example 3/2 will be always 1.5, and never 1. Just
+ like if you are using a calculator.</span></p>
+
+ <p>If you want to give a numerical value directly in the
+ template, then you write for example: <code class="inline-code">150</code> or
+ <code class="inline-code">-90.05</code> or <code class="inline-code">0.001</code>. (More
+ details regarding the syntax can be found <a href="dgui_template_exp.html#dgui_template_exp_direct_number">later</a>.)</p>
+ </li>
+
+ <li>
+ <p>Boolean: A boolean value represents a logical true
+ or false (yes or no). For example, if a the visitor has been
+ logged in or not. Typically you use booleans as the condition of
+ the <code class="inline-code">if</code> directive, like <code class="inline-code"><#if
+ loggedIn
+ ><em class="code-color">...</em></#if></code> or
+ <code class="inline-code"><#if price ==
+ 0><em class="code-color">...</em></#if></code>; in
+ the last case the result of the <code class="inline-code">price == 0</code>
+ part is a boolean value.</p>
+
+ <p>In the templates you can directly specify a boolean with
+ the reserved words <code class="inline-code">true</code> and
+ <code class="inline-code">false</code>.</p>
+ </li>
+
+ <li>
+ <p>Date: A date variable stores date/time related
+ data. It has three variations:</p>
+
+ <ul>
+ <li>
+ <p>A date with day precision (often referred simply as
+ "date") as April 4, 2003</p>
+ </li>
+
+ <li>
+ <p>Time of day (without the date part), as 10:19:18 PM.
+ Time is stored with millisecond precision.</p>
+ </li>
+
+ <li>
+ <p>Date-time (sometimes called "time stamp") as April 4,
+ 2003 10:19:18 PM. The time part is stored with millisecond
+ precision.</p>
+ </li>
+ </ul>
+
+ <p>Unfortunately, because of the limitations of the Java
+ platform, FreeMarker sometimes can't decide which parts of the
+ date are in use (i.e., if it is date-time, or a time of day,
+ etc.). The solution for this problem is an advanced topic that
+ will be discussed <a href="ref_builtins_date.html#ref_builtin_date_datetype">later</a>.</p>
+
+ <p>It is possible to define date values directly in
+ templates, but this is an advanced topic that will be explained
+ <a href="ref_builtins_string.html#ref_builtin_string_date">later</a>.</p>
+ </li>
+ </ul>
+
+ <p>Bear in mind that FreeMarker distinguishes strings from
+ numbers and booleans, so the string <code class="inline-code">"150"</code> and the
+ number <code class="inline-code">150</code> are totally different. A number holds
+ a numerical value. A boolean holds a logical true or false. A string
+ holds an arbitrary sequence of characters.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_datamodel_container">Containers</h2>
+
+
+
+
+ <p>These are the values whose purpose is to contain other
+ variables; they are just containers. The contained variables are
+ often referred as <em>subvariables</em>. The container
+ types are:</p>
+
+ <ul>
+ <li>
+ <p>Hash: Associates a unique lookup name with each of
+ its subvariables. The name is an unrestricted string. A hash
+ <em>doesn't define an ordering</em> for the
+ subvariables in it. That is, there is no such thing as the first
+ subvariable, and the second subvariable, etc.; the variables are
+ just accessed by name.</p>
+ </li>
+
+ <li>
+ <p>Sequence: Associates an integer number with each
+ of its subvariables. The first subvariable is associated with 0,
+ the second with 1, the third to 2, and so on; the subvariables
+ are ordered. These numbers are often called the
+ <em>indexes</em> of the subvariables. Sequences are
+ usually dense, i.e., all indexes up to the index of the last
+ subvariable have an associated subvariable, but it's not
+ strictly necessary. The type of the subvariable values need not
+ be the same.</p>
+ </li>
+
+ <li>
+ <p>Collection: A collection, from the viewpoint of
+ the template author, is a restricted sequence. You cannot access
+ its size or retrieve its subvariables by index, but they can be
+ still listed with the <a href="ref_directive_list.html#ref.directive.list"><code>list</code>
+ directive</a>.</p>
+ </li>
+ </ul>
+
+ <p>Note that since <a href="dgui_datamodel_basics.html#topic.multitype">a value can
+ have multiple types</a>, it is possible for a value to be both a
+ hash and a sequence, in which case it would support index-based
+ access as well as access by lookup name. However, typically a
+ container will be either a hash or a sequence, not both.</p>
+
+ <p>As the value of the variables stored in hashes and sequences
+ (and collections) can be anything, it can be a hash or sequence (or
+ collection) as well. This way you can build arbitrarily deep
+ structures.</p>
+
+ <p>The data-model itself (or better said the root of it) is a
+ hash.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_15">Subroutines</h2>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_datamodel_method">Methods and functions</h3>
+
+
+ <a name="topic.designer.methodVariable"></a>
+
+
+
+ <p>A value that is a method or a function is used to calculate
+ another value, influenced by the parameters you give to it.</p>
+
+ <p><span class="marked-for-programmers">For programmer types:
+ Methods/functions are first-class values, just like in functional
+ programming languages. This means that functions/methods can be
+ the parameters or return values of other functions/methods, you
+ can assign them to variables, and so on.</span></p>
+
+ <p>Suppose that programmers have put the method variable
+ <code class="inline-code">avg</code> in the data-model that can be used to
+ calculate the average of numbers. If you give the 3 and 5 as
+ parameters when you access <code class="inline-code">avg</code>, then you get
+ the value 4.</p>
+
+ <p>The usage of methods will be explained <a href="dgui_template_exp.html#dgui_template_exp_methodcall">later</a>, but perhaps
+ this example helps to understand what methods are:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">The average of 3 and 5 is: ${avg(3, 5)}
+The average of 6 and 10 and 20 is: ${avg(6, 10, 20)}
+The average of the price of a python and an elephant is:
+${avg(animals.python.price, animals.elephant.price)}</pre></div>
+
+ <p>this will output:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">The average of 3 and 5 is: 4
+The average of 6 and 10 and 20 is: 12
+The average of the price of a python and an elephant is:
+4999.5</pre></div>
+
+ <p>What is the difference between a method and a function? As
+ far as the template author is concerned, nothing. Well not really
+ nothing, as methods typically come from the data-model (<span class="marked-for-programmers">as they reflect the methods of Java
+ objects</span>), and functions are defined in templates (with
+ the <a href="ref_directive_function.html#ref.directive.function"><code>function</code>
+ directive</a> -- an advanced topic), but both can be used on
+ the same way.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_datamodel_userdefdir">User-defined directives</h3>
+
+
+
+
+
+
+
+
+ <p>A value of this type can be used as user-defined directive
+ (with other words, as FreeMarker tag). An user-defined directive
+ is a subroutine, something like a little reusable template
+ fragment. But this is an advanced topic that will be explained
+ <a href="dgui_misc_userdefdir.html">later</a> in its own
+ chapter.</p>
+
+ <p><span class="marked-for-programmers">For programmer types:
+ user-defined directives (such as macros), are first-class values
+ too, just like functions/methods are.</span></p>
+
+ <p>Just to get an idea about user-defined directives (so just
+ ignore this if you won't understand), assume we have a variable,
+ <code class="inline-code">box</code>, whose value is a user-defined directive
+ that prints some kind of fancy HTML message box with a title bar
+ and a message in it. The <code class="inline-code">box</code> variable could be
+ used in the template like this (for example):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@<strong>box</strong> title="Attention!">
+ Too much copy-pasting may leads to
+ maintenance headaches.
+</@<strong>box</strong>></pre></div>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="autoid_16">Function/method versus user-defined directive</h3>
+
+
+ <p>This is for advanced users again (so ignore it if you don't
+ understand). It's a frequent dilemma if you should use a
+ function/method or an user-defined directive to implement
+ something. The rule of thumb is: Implement the facility as
+ user-defined directive instead of as function/method if:</p>
+
+ <ul>
+ <li>
+ <p>... the output (the return value) is markup (HTML, XML,
+ etc.). The main reason is that the result of functions are
+ subject to automatic XML-escaping (due to the nature of
+ <code class="inline-code">${<em class="code-color">...</em>}</code>), while
+ the output of user-defined directives are not (due to the
+ nature of
+ <code class="inline-code"><@<em class="code-color">...</em>></code>;
+ its output is assumed to be markup, and hence already
+ escaped).</p>
+ </li>
+
+ <li>
+ <p>... it's the side-effect that is important and not the
+ return value. For example, a directive whose purpose is to add
+ an entry to the server log is like that. (In fact you can't
+ have a return value for a user-defined directive, but some
+ kind of feedback is still possible by setting non-local
+ variables.)</p>
+ </li>
+
+ <li>
+ <p>... it will do flow control (like for example
+ <code class="inline-code">list</code> or <code class="inline-code">if</code> directives
+ do). You just can't do that with a function/method
+ anyway.</p>
+ </li>
+ </ul>
+
+ <p>The Java methods of FreeMarker-unaware Java objects are
+ normally visible as methods in templates, regardless of the nature
+ of the Java method. That said, you have no choice there.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_17">Miscellaneous</h2>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_datamodel_node">Nodes</h3>
+
+
+
+
+ <p>Node variables represent a node in a tree structure, and are
+ used mostly with <a href="xgui.html">XML processing</a>, which
+ is an advanced, and specialized topic.</p>
+
+ <p>Still, a quick overview <em>for advanced
+ users</em>: A node is similar to a sequence that stores
+ other nodes, which are often referred as the children nodes. A
+ node stores a reference to its container node, which is often
+ referred as the parent node. The main point of being a node is the
+ topological information; other data must be stored by utilizing
+ that a value can have multiple types. Like, a value may be both a
+ node and a number, in which case it can store a number as the
+ "pay-load". Apart from the topological information, a node can
+ store some metainformation as well: a node name, a node type
+ (string), and a node namespace (string). For example, if the node
+ symbolizes a <code class="inline-code">h1</code> element in an XHTML document,
+ then its name could be <code class="inline-code">"h1"</code>, it's node type
+ could be <code class="inline-code">"element"</code>, and it's namespace could be
+ <code class="inline-code">"http://www.w3.org/1999/xhtml"</code>. But it's up to
+ the designer of the data-model if what meaning these
+ metainformations have, and if they are used at all. The way of
+ retrieving the topological and metainformations is described <a href="ref_builtins_node.html">in a later chapter</a> (that you
+ don't have to understand at this point).</p>
+
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_datamodel_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc.html b/legacy-tests/build/test/1/dgui_misc.html
new file mode 100644
index 0000000..d406484
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-chapter">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Miscellaneous - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Miscellaneous">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc.html">
+<link rel="canonical" href="http://example.com/dgui_misc.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_template_valueinsertion.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_userdefdir.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="dgui_misc" itemprop="headline">Miscellaneous</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="dgui_misc_userdefdir.html" data-menu-target="dgui_misc_userdefdir">Defining your own directives</a></li><li><a class="page-menu-link" href="dgui_misc_var.html" data-menu-target="dgui_misc_var">Defining variables in the template</a></li><li><a class="page-menu-link" href="dgui_misc_namespace.html" data-menu-target="dgui_misc_namespace">Namespaces</a></li><li><a class="page-menu-link" href="dgui_misc_whitespace.html" data-menu-target="dgui_misc_white [...]
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc_alternativesyntax.html b/legacy-tests/build/test/1/dgui_misc_alternativesyntax.html
new file mode 100644
index 0000000..7615b36
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc_alternativesyntax.html
@@ -0,0 +1,110 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Alternative (square bracket) syntax - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Alternative (square bracket) syntax">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc_alternativesyntax.html">
+<link rel="canonical" href="http://example.com/dgui_misc_alternativesyntax.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous","Alternative (square bracket) syntax"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc_whitespace.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_misc_alternativesyntax" itemprop="headline">Alternative (square bracket) syntax</h1>
+</div></div> <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>This feature exists since FreeMarker 2.3.4.</p>
+ </div>
+<p>FreeMarker supports an alternative syntax, where
+ <code class="inline-code">[</code> and <code class="inline-code">]</code> is used instead of
+ <code class="inline-code"><</code> and <code class="inline-code">></code> in FreeMarker
+ directives and comments, for example:</p><ul>
+ <li>
+ Calling predefined directive: <code class="inline-code">[#list animals as
+ being]<em class="code-color">...</em>[/#list]</code>
+ </li>
+
+ <li>
+ Calling user-defined directive: <code class="inline-code">[@myMacro
+ /]</code>
+ </li>
+
+ <li>
+ Comment: <code class="inline-code">[#-- the comment --]</code>
+ </li>
+ </ul><p>To use the alternative syntax instead of the default one, start
+ the template with the <a href="ref_directive_ftl.html"><code>ftl</code> directive</a>
+ using the alternative syntax. If you don't know what is the
+ <code class="inline-code">ftl</code> directive, just start the template with
+ <code class="inline-code">[#ftl]</code>, and remember that it should be the very
+ first thing in the file (except that <a href="gloss.html#gloss.whiteSpace">white-space</a> can precede it). For
+ example, this is how the last example of the <a href="dgui_quickstart_template.html">Getting Started</a> looks with
+ the alternative syntax (assuming it's a complete template, not just a
+ fragment):</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><strong>[#ftl]</strong>
+<p>We have these animals:
+<table border=1>
+ <tr><th>Name<th>Price
+ <strong>[#list animals as being]</strong>
+ <tr>
+ <td>
+ <strong>[#if being.size = "large"]</strong><b><strong>[/#if]</strong>
+ ${being.name}
+ <strong>[#if being.size = "large"]</strong></b><strong>[/#if]</strong>
+ <td>${being.price} Euros
+ <strong>[/#list]</strong>
+</table></pre></div><p>The alternative (square bracket) and the default (angle bracket)
+ syntax are mutually exclusive within a template. That is, either the
+ whole template uses alternative syntax, or the whole template uses the
+ default syntax. If the template uses alternative syntax, things like
+ <code class="inline-code"><#if <em class="code-color">...</em>></code> are
+ count as static text, not as FTL tags. Similarly, if the template uses
+ the default syntax, things like <code class="inline-code">[#if
+ <em class="code-color">...</em>]</code> count as static text, not as
+ FTL tags.</p><p>If you start the file with <code class="inline-code">[#ftl
+ <em class="code-color">...</em>]</code> (where the
+ <code class="inline-code"><em class="code-color">...</em></code> stands for the
+ optional parameters; of course <code class="inline-code">[#ftl]</code> works too)
+ the file will surely use the alternative (square bracket) syntax. If
+ you start the file with <code class="inline-code"><#ftl
+ <em class="code-color">...</em>></code> the file will surely use
+ the normal (angle bracket) syntax. If there is no
+ <code class="inline-code">ftl</code> directive in the file, then the programmer
+ decides what the syntax will be by configuring FreeMarker <span class="marked-for-programmers">(programmers see
+ <code class="inline-code">Configuration.setTagSyntax(int)</code> in the API
+ javadocs)</span>. Most probably the programmers use the factory
+ default however. The factory default in 2.3.x is using the normal
+ syntax. The factory default in 2.4.x will be auto-detection, which
+ means that the first FreeMarker tag determines the syntax (it can be
+ anything, not just <code class="inline-code">ftl</code>).</p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_whitespace.html"><span>Previous</span></a><a class="paging-arrow next" href="pgui.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc_namespace.html b/legacy-tests/build/test/1/dgui_misc_namespace.html
new file mode 100644
index 0000000..fdde9f7
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc_namespace.html
@@ -0,0 +1,340 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Namespaces - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Namespaces">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc_namespace.html">
+<link rel="canonical" href="http://example.com/dgui_misc_namespace.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous","Namespaces"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc_var.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_whitespace.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_misc_namespace" itemprop="headline">Namespaces</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#autoid_25" data-menu-target="autoid_25">Creating a library</a></li><li><a class="page-menu-link" href="#autoid_26" data-menu-target="autoid_26">Writing the variables of imported namespaces</a></li><li><a class="page-menu-link" href="#autoid_27" data-menu-target="autoid_27">Namespaces and data-model</a></li><li><a class="page-menu-link" href="#autoid_28" data-menu-target="autoid_28">The life-cycle of namespaces</a></li><li><a class="page-menu-link" [...]
+ variables that you have created with <code class="inline-code">assign</code> and
+ <code class="inline-code">macro</code> directives, as can be seen from the <a href="dgui_misc_var.html">previous chapter</a>. A set of variables
+ like this is called a <strong>namespace</strong>. In
+ simple cases you use only one namespace, the so-called <strong>main namespace</strong>. You don't realize this, since
+ normally you use only this namespace.</p><p>But if you want to build reusable collection of macros,
+ functions and other variables -- usually referred as <strong>library</strong> by lingo -- the usage of multiple
+ namespaces becomes inevitable. Just consider if you have a big
+ collection of macros, that you use in several projects, or even you
+ want to share it with other people. It becomes impossible to be sure
+ that the library does not have a macro (or other variable) with the
+ same name as the name of a variable in the data-model, or with the
+ same name as a the name of a variable in another library used in the
+ template. In general, variables can clobber each other because of the
+ name clashes. So you should use a separate namespace for the variables
+ of each library.</p>
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_25">Creating a library</h2>
+
+
+ <p>Let's create a simple library. Assume you commonly need the
+ variables <code class="inline-code">copyright</code> and <code class="inline-code">mail</code>
+ (before you ask, macros <em>are</em> variables):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro copyright date>
+ <p>Copyright (C) ${date} Julia Smith. All rights reserved.</p>
+</#macro>
+
+<#assign mail = "jsmith@acme.com"></pre></div>
+
+ <p>Store the above in the file <code class="inline-code">lib/my_test.ftl</code>
+ (in the directory where you store the templates). Assume you want to
+ use this in <code class="inline-code">aWebPage.ftl</code>. If you use
+ <code class="inline-code"><#include "/lib/my_test.ftl"></code> in the
+ <code class="inline-code">aWebPage.ftl</code>, then it will create the two
+ variables in the main namespace, and it is not good now, since you
+ want them to be in a namespace that is used exclusively by the ``My
+ Test Library''. Instead of <code class="inline-code">include</code> you have to
+ use <a href="ref_directive_import.html#ref.directive.import"><code>import</code>
+ directive</a>. This directive is, at the first glance, similar to
+ <code class="inline-code">include</code>, but it will create an empty namespace
+ for <code class="inline-code">lib/my_test.ftl</code> and will execute that there.
+ <code class="inline-code">lib/my_test.ftl</code> will find itself in an clean new
+ world, where only the variables of data-model are present (since
+ they are visible from everywhere), and will create the two variables
+ in this new world. That's fine for now, but you want to access the
+ two variables from <code class="inline-code">aWebPage.ftl</code>, and that uses
+ the main namespace, so it can't see the variables of the other
+ namespace. The solution is that the <code class="inline-code">import</code>
+ directive not only creates the new namespace, but a new hash
+ variable in the namespace used by the caller of
+ <code class="inline-code">import</code> (the main namespace in this case), that
+ will act as a gate into the newly created namespace. So this is how
+ <code class="inline-code">aWebPage.ftl</code> will look like:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#import "/lib/my_test.ftl" as <strong>my</strong>> <#-- the hash called "my" will be the "gate" -->
+<@<strong>my</strong>.copyright date="1999-2002"/>
+${<strong>my</strong>.mail}</pre></div>
+
+ <p>Note how it accesses the variables in the namespace created
+ for <code class="inline-code">/lib/my_test.ftl</code> using the newly created
+ namespace accessing hash, <code class="inline-code">my</code>. This will
+ print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.</p>
+jsmith@acme.com</pre></div>
+
+ <p>If you would have a variable called <code class="inline-code">mail</code> or
+ <code class="inline-code">copyright</code> in the main namespace, that would not
+ cause any confusion, since the two templates use separated
+ namespaces. For example, modify the <code class="inline-code">copyright</code>
+ macro in <code class="inline-code">lib/my_test.ftl</code> to this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro copyright date>
+ <p>Copyright (C) ${date} Julia Smith. All rights reserved.
+ <br>Email: <strong>${mail}</strong></p>
+</#macro></pre></div>
+
+ <p>and then replace <code class="inline-code">aWebPage.ftl</code> with
+ this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#import "/lib/my_test.ftl" as my>
+<strong><#assign mail="fred@acme.com"></strong>
+<@my.copyright date="1999-2002"/>
+${my.mail}
+${mail}</pre></div>
+
+ <p>and the output will be this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <p>Copyright (C) 1999-2002 Julia Smith. All rights reserved.
+ <br>Email: <strong>jsmith@acme.com</strong></p>
+jsmith@acme.com
+fred@acme.com</pre></div>
+
+ <p>This is like that because when you have called the
+ <code class="inline-code">copyright</code> macro, FreeMarker has temporarily
+ switch to the namespace that was created by the
+ <code class="inline-code">import</code> directive for
+ <code class="inline-code">/lib/my_test.ftl</code>. Thus, the
+ <code class="inline-code">copyright</code> macro always sees the
+ <code class="inline-code">mail</code> variable that exists there, and not the
+ other <code class="inline-code">mail</code> that exists in the main
+ namespace.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_26">Writing the variables of imported namespaces</h2>
+
+
+ <p>Occasionally you may want to create or replace a variable in
+ an imported namespace. You can do this with the
+ <code class="inline-code">assign</code> directive, if you use its
+ <code class="inline-code">namespace</code> parameter. For example, this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#import "/lib/my_test.ftl" as my>
+${my.mail}
+<#assign mail="jsmith@other.com" <strong>in my</strong>>
+${my.mail}</pre></div>
+
+ <p>will output this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">jsmith@acme.com
+jsmith@other.com</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_27">Namespaces and data-model</h2>
+
+
+ <p>The variables of the data-model are visible from everywhere.
+ For example, if you have a variable called <code class="inline-code">user</code>
+ in the data-model, <code class="inline-code">lib/my_test.ftl</code> will access
+ that, exactly as <code class="inline-code">aWebPage.ftl</code> does:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro copyright date>
+ <p>Copyright (C) ${date} <strong>${user}</strong>. All rights reserved.</p>
+</#macro>
+
+<#assign mail = "<strong>${user}</strong>@acme.com"></pre></div>
+
+ <p>If <code class="inline-code">user</code> is ``Fred'', then the usual
+ example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#import "/lib/my_test.ftl" as my>
+<@my.copyright date="1999-2002"/>
+${my.mail}</pre></div>
+
+ <p>will print this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <p>Copyright (C) 1999-2002 Fred. All rights reserved.</p>
+Fred@acme.com</pre></div>
+
+ <p>Don't forget that the variables in the namespace (the
+ variables you create with <code class="inline-code">assign</code> or
+ <code class="inline-code">macro</code> directives) have precedence over the
+ variables of the data-model when you are in that namespace. Thus,
+ the contents of data-model does not interfere with the variables
+ created by the library.</p>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>In some unusual applications you want to create variables in
+ the template those are visible from all namespaces, exactly like
+ the variables of the data-model. But you can't change the
+ data-model with templates. Still, it is possible to achieve
+ similar result with the <code class="inline-code">global</code> directive; read
+ the <a href="ref_directive_global.html#ref.directive.global">reference</a> for more
+ details.</p>
+ </div>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_28">The life-cycle of namespaces</h2>
+
+
+ <p>A namespace is identified by the path that was used with the
+ <code class="inline-code">import</code> directive. If you try to
+ <code class="inline-code">import</code> with the same path for multiple times, it
+ will create the namespace and run the template specified by the path
+ for the very first invocation of <code class="inline-code">import</code> only. The
+ later <code class="inline-code">import</code>s with the same path will just create
+ a ``gate'' hash to the same namespace. For example, let this be the
+ <code class="inline-code">aWebPage.ftl</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#import "/lib/my_test.ftl" as my>
+<#import "/lib/my_test.ftl" as foo>
+<#import "/lib/my_test.ftl" as bar>
+${my.mail}, ${foo.mail}, ${bar.mail}
+<#assign mail="jsmith@other.com" in my>
+${my.mail}, ${foo.mail}, ${bar.mail}</pre></div>
+
+ <p>The output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">jsmith@acme.com, jsmith@acme.com, jsmith@acme.com
+jsmith@other.com, jsmith@other.com, jsmith@other.com</pre></div>
+
+ <p>since you see the same namespace through
+ <code class="inline-code">my</code>, <code class="inline-code">foo</code> and
+ <code class="inline-code">bar</code>.</p>
+
+ <p>Note that namespaces are not hierarchical, they exist
+ independently of each other. That is, if you
+ <code class="inline-code">import</code> namespace N2 while you are in name space
+ N1, N2 will not be inside N1. N1 just gets a hash by which it can
+ access N2. This is the same N2 namespace that you would access if,
+ say, you <code class="inline-code">import</code> N2 when you are in the main
+ namespace.</p>
+
+ <p>Each <a href="gloss.html#gloss.templateProcessingJob">template
+ processing job</a> has its own private set of namespaces. Each
+ template-processing job is a separated cosmos that exists only for
+ the short period of time while the given page is being rendered, and
+ then it vanishes with all its populated namespaces. Thus, whenever
+ we say that ``<code class="inline-code">import</code> is called for the first
+ time'' and such, we are always talking in the context of a single
+ template processing job.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_29">Writing libraries for other people</h2>
+
+
+
+
+ <p>If you have written a good quality library that can be useful
+ for other people, you may want to make it available on the Internet
+ (like on <a href="http://freemarker.org/libraries.html">http://freemarker.org/libraries.html</a>).
+ To prevent clashes with the names of libraries used by other
+ authors, and to make it easy to write libraries that import other
+ published libraries, there is a de-facto standard that specifies the
+ format of library paths. The standard is that the library must be
+ available (importable) for templates and other libraries with a path
+ like this:</p>
+
+ <p><code class="inline-code">/lib/<em class="code-color">yourcompany.com</em>/<em class="code-color">your_library</em>.ftl</code></p>
+
+ <p>For example if you work for Example Inc. that owns the
+ www.example.com homepage, and you develop a widget library, then the
+ path of the FTL file to import should be:</p>
+
+ <p><code class="inline-code">/lib/example.com/widget.ftl</code></p>
+
+ <p>Note that the www is omitted. The part after the 3rd slash can
+ contain subdirectories such as:</p>
+
+ <p><code class="inline-code">/lib/example.com/commons/string.ftl</code></p>
+
+ <p>An important rule is that the path should not contain
+ upper-case letters. To separate words, use <code class="inline-code">_</code>, as
+ in <code class="inline-code">wml_form</code> (not
+ <code class="inline-code">wmlForm</code>).</p>
+
+ <p>Note that if you do not develop the library for a company or
+ organization, you should use the URL of the project homepage, such
+ as <code class="inline-code">/lib/example.sourceforge.net/example.ftl</code>, or
+ <code class="inline-code">/lib/geocities.com/jsmith/example.ftl</code>.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_var.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_whitespace.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc_userdefdir.html b/legacy-tests/build/test/1/dgui_misc_userdefdir.html
new file mode 100644
index 0000000..032a114
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc_userdefdir.html
@@ -0,0 +1,530 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Defining your own directives - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Defining your own directives">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc_userdefdir.html">
+<link rel="canonical" href="http://example.com/dgui_misc_userdefdir.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous","Defining your own directives"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_var.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_misc_userdefdir" itemprop="headline">Defining your own directives</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#autoid_21" data-menu-target="autoid_21">Basics</a></li><li><a class="page-menu-link" href="#autoid_22" data-menu-target="autoid_22">Parameters</a></li><li><a class="page-menu-link" href="#autoid_23" data-menu-target="autoid_23">Nested content</a></li><li><a class="page-menu-link" href="#dgui_misc_userdefdir_loopvar" data-menu-target="dgui_misc_userdefdir_loopvar">Macros with loop variables</a></li><li><a class="page-menu-link" href="#autoid_24" da [...]
+ directives can be defined using the <code class="inline-code">macro</code>
+ directive. <span class="marked-for-programmers">Java programmers who want to
+ implement directives in Java Language, rather than in a template,
+ should use
+ <code class="inline-code">freemarker.template.TemplateDirectiveModel</code> (see
+ <a href="pgui_datamodel_directive.html">more
+ here...</a>).</span></p>
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_21">Basics</h2>
+
+
+
+
+ <p>A macro is a template fragment associated with a variable. You
+ can use that variable in your template as a user-defined directive,
+ so it helps in repetitive tasks. For example, this creates a macro
+ variable that prints a big ``Hello Joe!'':</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><strong><#macro greet></strong>
+ <font size="+2">Hello Joe!</font>
+<strong></#macro></strong></pre></div>
+
+ <p>The <code class="inline-code">macro</code> directive itself does not print
+ anything; it just creates the macro variable, so there will be a
+ variable called <code class="inline-code">greet</code>. Things between the
+ <code class="inline-code"><#macro greet></code> and
+ <code class="inline-code"></#macro></code> (called <strong>macro definition body</strong>) will be executed only
+ when you use the variable as directive. You use user-defined
+ directives by writing <code class="inline-code">@</code> instead of
+ <code class="inline-code">#</code> in the FTL tag. Use the variable name as the
+ directive name. Also, the <a href="gloss.html#gloss.endTag">end-tag</a> for user-defined directives is
+ mandatory. So you use <code class="inline-code">greet</code> like this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet></@greet></pre></div>
+
+ <p>But since
+ <code class="inline-code"><<em class="code-color">anything</em>></<em class="code-color">anything</em>></code>
+ is equivalent with
+ <code class="inline-code"><<em class="code-color">anything</em>/></code> you
+ should use this shorter form (that is familiar for you if you know
+ <a href="gloss.html#gloss.XML">XML</a>):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet/></pre></div>
+
+ <p>This will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <font size="+2">Hello Joe!</font>
+ </pre></div>
+
+ <p>But macros can do much more, since the thing between
+ <code class="inline-code"><#macro <em class="code-color">...</em>></code> and
+ <code class="inline-code"></#macro></code> is a template fragment, thus it
+ can contain interpolations
+ (<code class="inline-code">${<em class="code-color">...</em>}</code>) and FTL tags
+ (e.g. <code class="inline-code"><#if
+ <em class="code-color">...</em>><em class="code-color">...</em></#if></code>).</p>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>Programmers will say on
+ <code class="inline-code"><@<em class="code-color">...</em>></code> that
+ you <strong>call</strong> the macro.</p>
+ </div>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_22">Parameters</h2>
+
+
+ <p>Let's improve the <code class="inline-code">greet</code> macro so it can use
+ arbitrary name, not only ``Joe''. For this purpose you can use
+ <strong>parameters</strong>. You define the
+ parameters after the name of the macro in the
+ <code class="inline-code">macro</code> directive. Here we define one parameter for
+ the <code class="inline-code">green</code> macro,
+ <code class="inline-code">person</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro greet <strong>person</strong>>
+ <font size="+2">Hello <strong>${person}</strong>!</font>
+</#macro></pre></div>
+
+ <p>and then you can use this macro as:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet <strong>person="Fred"</strong>/> and <@greet <strong>person="Batman"</strong>/></pre></div>
+
+ <p>which is similar to HTML syntax. This will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <font size="+2">Hello <strong>Fred</strong>!</font>
+ and <font size="+2">Hello <strong>Batman</strong>!</font>
+ </pre></div>
+
+ <p>As you can see, the actual value of the macro parameter is
+ accessible in the macro definition body as a variable
+ (<code class="inline-code">person</code>). As with <a href="gloss.html#gloss.predefinedDirective">predefined directives</a>,
+ the value of a parameter (the right side of <code class="inline-code">=</code>) is
+ an <a href="dgui_template_exp.html">FTL expression</a>. Thus,
+ unlike with HTML, the quotation marks around
+ <code class="inline-code">"Fred"</code> and <code class="inline-code">"Batman"</code> are not
+ optional. <code class="inline-code"><@greet person=Fred/></code> would mean
+ that you use the value of variable <code class="inline-code">Fred</code> for the
+ <code class="inline-code">person</code> parameter, rather than the string
+ <code class="inline-code">"Fred"</code>. Of course parameter value need not be a
+ string, it can be number, boolean, hash, sequence, ...etc., also you
+ can use complex expression on the left side of <code class="inline-code">=</code>
+ (e.g. <code class="inline-code">someParam=(price + 50)*1.25</code>).</p>
+
+ <p>User-defined directives can have multiple parameters. For
+ example, add a new parameter <code class="inline-code">color</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro greet person <strong>color</strong>>
+ <font size="+2" color="${color}">Hello ${person}!</font>
+</#macro></pre></div>
+
+ <p>and then you can use this macro like:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet person="Fred" color="black"/></pre></div>
+
+ <p>The order of parameters is not important, so this is
+ equivalent with the previous:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet color="black" person="Fred"/></pre></div>
+
+ <p>When you call the macro, you can use only parameters that you
+ have defined in the <code class="inline-code">macro</code> directive (in this
+ case: <code class="inline-code">person</code> and <code class="inline-code">color</code>). So if
+ you try <code class="inline-code"><@greet person="Fred" color="black"
+ background="green"/></code> then you will get an error, since
+ you haven't mentioned parameter <code class="inline-code">background</code> in the
+ <code class="inline-code"><#macro
+ <em class="code-color">...</em>></code>.</p>
+
+ <p>Also, you must give value for all parameters that you have
+ defined for the macro. So if you try <code class="inline-code"><@greet
+ person="Fred"/></code> then you will get an error, since you
+ forgot to specify the value of <code class="inline-code">color</code>. However, it
+ often happens that you would specify the same value for a parameter
+ in most cases, so you want to specify the value only when you want a
+ different value for it than the usual. This can be achieved if you
+ specify the parameter in the <code class="inline-code">macro</code> directive as
+ <code class="inline-code"><em class="code-color">param_name</em>=<em class="code-color">usual_value</em></code>.
+ For example, you want to use <code class="inline-code">"black"</code> for
+ <code class="inline-code">color</code> if you don't specify value for that
+ parameter when you use the <code class="inline-code">greet</code>
+ directive:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro greet person color<strong>="black"</strong>>
+ <font size="+2" color="${color}">Hello ${person}!</font>
+</#macro></pre></div>
+
+ <p>Now <code class="inline-code"><@greet person="Fred"/></code> is OK,
+ since it is equivalent with <code class="inline-code"><@greet person="Fred"
+ color="black"/></code>, thus the value of
+ <code class="inline-code">color</code> parameter is known. If you want
+ <code class="inline-code">"red"</code> for <code class="inline-code">color</code>, then you
+ write <code class="inline-code"><@greet person="Fred" color="red"/></code>,
+ and this value will override the usual value specified with the
+ <code class="inline-code">macro</code> directive, so the value of
+ <code class="inline-code">color</code> parameter will be
+ <code class="inline-code">"red"</code>.</p>
+
+ <p>Also, it is important to realize that -- according to the
+ already explained <a href="dgui_template_exp.html">FTL expression
+ rules</a> -- <code class="inline-code">someParam=foo</code> and
+ <code class="inline-code">someParam="${foo}"</code> are very different. In the
+ fist case, you use the value of variable <code class="inline-code">foo</code> as
+ the value of the parameter. In the second case, you use a <a href="dgui_template_exp.html#dgui_template_exp_stringop_interpolation">string literal
+ with interpolation</a>, so the value of the parameter will be a
+ string -- in this case, the value of <code class="inline-code">foo</code> rendered
+ to text -- regardless of the type (as number, date, etc.) of
+ <code class="inline-code">foo</code>. Or, another example:
+ <code class="inline-code">someParam=3/4</code> and
+ <code class="inline-code">someParam="${3/4}"</code> are different. If the
+ directive wants a numerical value for <code class="inline-code">someParam</code>,
+ it will not like the second variation. Do not exchange these.</p>
+
+ <p>A very important aspect of macro parameters is that they are
+ local variables. For more information about local variables please
+ read: <a href="dgui_misc_var.html">Defining variables in the template</a></p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_23">Nested content</h2>
+
+
+ <p>Custom directive can have nested content, similarly as
+ predefined directives like <code class="inline-code"><#if
+ <em class="code-color">...</em>><em class="code-color">nested
+ content</em></#if></code> can have. For example,
+ this creates a macro that draws borders around its nested
+ content:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro border>
+ <table border=4 cellspacing=0 cellpadding=4><tr><td>
+ <strong><#nested></strong>
+ </tr></td></table>
+</#macro></pre></div>
+
+ <p>The <code class="inline-code"><#nested></code> directive executes the
+ template fragment between the start-tag and end-tags of the
+ directive. So if you do this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@border>The bordered text</@border></pre></div>
+
+ <p>the output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <table border=4 cellspacing=0 cellpadding=4><tr><td>
+ The bordered text
+ </td></tr></table>
+ </pre></div>
+
+ <p>The <code class="inline-code">nested</code> directive can be called for
+ multiple times, for example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro do_thrice><strong>
+ <#nested>
+ <#nested>
+ <#nested></strong>
+</#macro>
+<@do_thrice>
+ Anything.
+</@do_thrice></pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> Anything.
+ Anything.
+ Anything.</pre></div>
+
+ <p>If you don't use the nested directive, then the nested content
+ will not be executed. Thus, if you accidentally use the
+ <code class="inline-code">greet</code> directive like this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@greet person="Joe">
+ Anything.
+</@greet></pre></div>
+
+ <p>then FreeMarker will not see this as an error, and simply
+ prints:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"><font size="+2">Hello Joe!</font></pre></div>
+
+ <p>and the nested content will be ignored, since the
+ <code class="inline-code">greet</code> macro never uses <code class="inline-code">nested</code>
+ directive.</p>
+
+ <p>The nested content can be anything that is valid FTL,
+ including other user-defined directives. Thus this is OK:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@border>
+ <ul>
+ <@do_thrice>
+ <li><@greet person="Joe"/>
+ </@do_thrice>
+ </ul>
+</@border></pre></div>
+
+ <p>and will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> <table border=4 cellspacing=0 cellpadding=4><tr><td>
+ <ul>
+ <li><font size="+2">Hello Joe!</font>
+
+ <li><font size="+2">Hello Joe!</font>
+
+ <li><font size="+2">Hello Joe!</font>
+
+ </ul>
+
+ </tr></td></table></pre></div>
+
+ <p>The <a href="dgui_misc_var.html">local variables</a> of a
+ macro are not visible in the nested content. Say, this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro repeat count>
+ <#local y = "test">
+ <#list 1..count as x>
+ ${y} ${count}/${x}: <#nested>
+ </#list>
+</#macro>
+<@repeat count=3>${y!"?"} ${x!"?"} ${count!"?"}</@repeat></pre></div>
+
+ <p>will print this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> test 3/1: ? ? ?
+ test 3/2: ? ? ?
+ test 3/3: ? ? ?</pre></div>
+
+ <p>because the <code class="inline-code">y</code>, <code class="inline-code">x</code> and
+ <code class="inline-code">count</code> are the local (private) variables of the
+ macro, and are not visible from outside the macro definition.
+ Furthermore, a different set of local variables is used for each
+ macro call, so this will not cause confusion:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro test foo>${foo} (<#nested>) ${foo}</#macro>
+<@test foo="A"><@test foo="B"><@test foo="C"/></@test></@test></pre></div>
+
+ <p>and will print this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">A (B (C () C) B) A</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_misc_userdefdir_loopvar">Macros with loop variables</h2>
+
+
+
+
+ <p>Predefined directives like <code class="inline-code">list</code> can use
+ so-called loop variables; you should read <a href="dgui_misc_var.html">Defining variables in the template</a> to understand loop variables.</p>
+
+ <p>User-defined directives can also have loop variables. For
+ example, let's extend the <code class="inline-code">do_thrice</code> directive of
+ the earlier examples so it exposes the current repetition number as
+ a loop variable. As with the predefined directives (as
+ <code class="inline-code">list</code>) the <em>name</em> of loop
+ variables is given when you call the directive (as
+ <code class="inline-code">foo</code> in <code class="inline-code"><#list foos as
+ foo><em class="code-color">...</em></#list></code>),
+ while the <em>value</em> of the variables is set by the
+ directive itself.</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro do_thrice>
+ <#nested <strong>1</strong>>
+ <#nested <strong>2</strong>>
+ <#nested <strong>3</strong>>
+</#macro>
+<@do_thrice <strong>; x</strong>> <#-- user-defined directive uses ";" instead of "as" -->
+ ${<strong>x</strong>} Anything.
+</@do_thrice></pre></div>
+
+ <p>This will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> 1 Anything.
+ 2 Anything.
+ 3 Anything.
+ </pre></div>
+
+ <p>The syntactical rule is that you pass the actual value of the
+ loop variable for a certain "loop" (i.e. repetition of the nested
+ content) as the parameter of <code class="inline-code">nested</code> directive (of
+ course the parameter can by arbitrary expression). The name of the
+ loop variable is specified in the user-defined directive open tag
+ (<code class="inline-code"><@...></code>) after the parameters and a
+ semicolon.</p>
+
+ <p>A macro can use more the one loop variable (the order of
+ variables is significant):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#macro repeat count>
+ <#list 1..count as x>
+ <#nested <strong>x, x/2, x==count</strong>>
+ </#list>
+</#macro>
+<@repeat count=4 ; <strong>c, halfc, last</strong>>
+ ${<strong>c</strong>}. ${<strong>halfc</strong>}<#if <strong>last</strong>> Last!</#if>
+</@repeat></pre></div>
+
+ <p>The output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> 1. 0.5
+ 2. 1
+ 3. 1.5
+ 4. 2 Last!
+ </pre></div>
+
+ <p>It is not a problem if you specify different number of loop
+ variables in the user-defined directive start-tag (that is, after
+ the semicolon) than with the <code class="inline-code">nested</code> directive. If
+ you specify less loop variables after the semicolon, then simply you
+ will not see the last few values that the <code class="inline-code">nested</code>
+ directive provides, since there is no loop variable to hold those
+ values. So these are all OK:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><@repeat count=4 ; <strong>c, halfc, last</strong>>
+ ${c}. ${halfc}<#if last> Last!</#if>
+</@repeat>
+<@repeat count=4 ; <strong>c, halfc</strong>>
+ ${c}. ${halfc}
+</@repeat>
+<@repeat count=4>
+ Just repeat it...
+</@repeat></pre></div>
+
+ <p>If you specify more variables after the semicolon than with
+ the <code class="inline-code">nested</code> directive, then the last few loop
+ variables will not be created (i.e. will be undefined in the nested
+ content).</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_24">More about user-defined directives and macros</h2>
+
+
+ <p>Now you may read the relevant parts of the FreeMarker
+ Reference:</p>
+
+ <ul>
+ <li>
+ <a href="ref_directive_userDefined.html#ref.directive.userDefined">user-defined
+ directive call</a>
+ </li>
+
+ <li>
+ <a href="ref_directive_macro.html#ref.directive.macro"><code>macro</code>
+ directive</a>
+ </li>
+ </ul>
+
+ <p>You can define methods in FTL as well, see <a href="ref_directive_function.html#ref.directive.function">the <code>function</code>
+ directive</a>.</p>
+
+ <p>Also, you may interested in namespaces: <a href="dgui_misc_namespace.html">Namespaces</a>. Namespaces help you to organize
+ and reuse your commonly used macros.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_var.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc_var.html b/legacy-tests/build/test/1/dgui_misc_var.html
new file mode 100644
index 0000000..8dadc20
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc_var.html
@@ -0,0 +1,161 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Defining variables in the template - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Defining variables in the template">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc_var.html">
+<link rel="canonical" href="http://example.com/dgui_misc_var.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous","Defining variables in the template"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc_userdefdir.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_namespace.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_misc_var" itemprop="headline">Defining variables in the template</h1>
+</div></div><p>As we have described, a template can use the variables defined
+ in the data-model. A template can also define variables outside the
+ data-model for its own use. These temporary variables can be created
+ and replaced using FTL directives. Note that each <a href="gloss.html#gloss.templateProcessingJob">template processing job</a>
+ has its own private set of these variables that exists while the given
+ page is being rendered. This variable set is initially empty, and will
+ be thrown away when the template processing job has been
+ finished.</p><p>You access a variable that you have defined in the template
+ exactly as if it were a variable in the data-model root. The variable
+ has precedence over any variable of the same name defined in the
+ data-model. That is, if you define a variable called ``foo'' and
+ coincidentally, there is a ``foo'' in the data-model as well, then the
+ variable created in the template will hide (not overwrite!) the
+ variable in the data-model root. For example,
+ <code class="inline-code">${foo}</code> will print the value of the variable created
+ in the template.</p><p>There are 3 kind of variables that are defined in a
+ template:</p><ul>
+ <li>
+ <p><strong>``plain'' variables</strong>: They
+ are accessible from everywhere in the template, or from the
+ templates inserted with <code class="inline-code">include</code> directive. You
+ can create and replace these variables with the <a href="ref_directive_assign.html#ref.directive.assign"><code>assign</code></a> or
+ <a href="ref_directive_macro.html#ref.directive.macro"><code>macro</code>
+ directives</a>.</p>
+ </li>
+
+ <li>
+ <p><strong>Local variables</strong>: They can
+ only be set inside a <a href="gloss.html#gloss.macroDefinitionBody">macro definition body</a>,
+ and are only visible from there. A local variable only exists for
+ the duration of a macro call. You can create and replace local
+ variables inside macro definition bodies with the <a href="ref_directive_local.html#ref.directive.local"><code>local</code>
+ directive</a>.</p>
+ </li>
+
+ <li>
+ <p><strong>Loop variables</strong>: Loop
+ variables are created automatically by directives like <a href="ref_directive_list.html#ref.directive.list"><code>list</code></a>, and
+ they only exist between the start-tag and end-tag of the
+ directive. <a href="ref_directive_macro.html#ref.directive.macro">Macro</a>
+ parameters are local variables, not loop variables.</p>
+ </li>
+ </ul><p>Example: Create and replace variables with
+ <code class="inline-code">assign</code>:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign x = 1> <#-- create variable x -->
+${x}
+<#assign x = x + 3> <#-- replace variable x -->
+${x}</pre></div><p>Output:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output">1
+4</pre></div><p>Local variables hide (not overwrite) ``plain'' variables of the
+ same name. Loop variables hide (not overwrite) local and ``plain''
+ variables of the same name. For example:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign x = "plain">
+1. ${x} <#-- we see the plain var. here -->
+<@test/>
+6. ${x} <#-- the value of plain var. was not changed -->
+<#list ["loop"] as x>
+ 7. ${x} <#-- now the loop var. hides the plain var. -->
+ <#assign x = "plain2"> <#-- replace the plain var, hiding does not mater here -->
+ 8. ${x} <#-- it still hides the plain var. -->
+</#list>
+9. ${x} <#-- the new value of plain var. -->
+
+<#macro test>
+ 2. ${x} <#-- we still see the plain var. here -->
+ <#local x = "local">
+ 3. ${x} <#-- now the local var. hides it -->
+ <#list ["loop"] as x>
+ 4. ${x} <#-- now the loop var. hides the local var. -->
+ </#list>
+ 5. ${x} <#-- now we see the local var. again -->
+</#macro></pre></div><p>the output:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output">1. plain
+ 2. plain
+ 3. local
+ 4. loop
+ 5. local
+6. plain
+ 7. loop
+ 8. loop
+9. plain2
+ </pre></div><p>An inner loop variable can hide an outer loop variable:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><#list ["loop 1"] as x>
+ ${x}
+ <#list ["loop 2"] as x>
+ ${x}
+ <#list ["loop 3"] as x>
+ ${x}
+ </#list>
+ ${x}
+ </#list>
+ ${x}
+</#list></pre></div><p>the output:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output"> loop 1
+ loop 2
+ loop 3
+ loop 2
+ loop 1</pre></div><p>Note that the value of a loop variable is set by the directive
+ invocation that has created it (the <code class="inline-code"><list
+ <em class="code-color">...</em>></code> tags in this case). There
+ is no other way to change the value of a loop variable (say, you can't
+ change its value with some kind of assignment directive). You can hide
+ temporarily a loop variable with another loop variable though, as you
+ have seen above.</p><p>Sometimes it happens that a variable hides the variable in the
+ data-model with the same name, but you want to read the variable of
+ the data-model. In this case you can use the <a href="dgui_template_exp.html#dgui_template_exp_var_special">special variable</a>
+ <code class="inline-code">globals</code>. For example, assume we have a variable
+ called <code class="inline-code">user</code> in the data-model with value ``Big
+ Joe'':</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign user = "Joe Hider">
+${user} <#-- prints: Joe Hider -->
+${.globals.user} <#-- prints: Big Joe --></pre></div><p>For information about syntax of variables please read: <a href="dgui_template_exp.html">The Template/Expressions</a></p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_userdefdir.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_namespace.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_misc_whitespace.html b/legacy-tests/build/test/1/dgui_misc_whitespace.html
new file mode 100644
index 0000000..0188b03
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_misc_whitespace.html
@@ -0,0 +1,287 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>White-space handling - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="White-space handling">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_misc_whitespace.html">
+<link rel="canonical" href="http://example.com/dgui_misc_whitespace.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Miscellaneous","White-space handling"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc_namespace.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_alternativesyntax.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_misc_whitespace" itemprop="headline">White-space handling</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#dgui_misc_whitespace_stripping" data-menu-target="dgui_misc_whitespace_stripping">White-space stripping</a></li><li><a class="page-menu-link" href="#autoid_30" data-menu-target="autoid_30">Using compress directive</a></li></ul> </div><p>The control of the <a href="gloss.html#gloss.whiteSpace">white-space</a> in a template is a
+ problem that to some extent haunts every template engine in the
+ business.</p><p>Let see this template. I have marked the components of template
+ with colors: <span class="marked-text">text</span>, <span class="marked-interpolation">interpolation</span>, <span class="marked-ftl-tag">FTL tag</span>. With the <em><span class="marked-invisible-text">[BR]</span></em>-s I visualize the <a href="gloss.html#gloss.lineBreak">line breaks</a>.</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><span class="marked-text"><p>List of users:<em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-ftl-tag"><#assign users = [{"name":"Joe", "hidden":false},<em><span class="marked-invisible-text">[BR]</span></em>
+ {"name":"James Bond", "hidden":true},<em><span class="marked-invisible-text">[BR]</span></em>
+ {"name":"Julia", "hidden":false}]></span><em><span class="marked-invisible-text">[BR]</span></em>
+<ul><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-ftl-tag"><#list users as user></span><em><span class="marked-invisible-text">[BR]</span></em>
+ <span class="marked-ftl-tag"><#if !user.hidden></span><em><span class="marked-invisible-text">[BR]</span></em>
+ <li><span class="marked-interpolation">${user.name}</span><em><span class="marked-invisible-text">[BR]</span></em>
+ <span class="marked-ftl-tag"></#if></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-ftl-tag"></#list></span><em><span class="marked-invisible-text">[BR]</span></em>
+</ul><em><span class="marked-invisible-text">[BR]</span></em>
+<p>That's all.</span></pre></div><p>If FreeMarker were to output all <span class="marked-text">text</span> as is, the output would be:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output"><span class="marked-text"><p>List of users:<em><span class="marked-invisible-text">[BR]</span></em>
+<em><span class="marked-invisible-text">[BR]</span></em>
+<ul><em><span class="marked-invisible-text">[BR]</span></em>
+<em><span class="marked-invisible-text">[BR]</span></em>
+ <em><span class="marked-invisible-text">[BR]</span></em>
+ <li></span>Joe<span class="marked-text"><em><span class="marked-invisible-text">[BR]</span></em>
+ <em><span class="marked-invisible-text">[BR]</span></em>
+<em><span class="marked-invisible-text">[BR]</span></em>
+ <em><span class="marked-invisible-text">[BR]</span></em>
+<em><span class="marked-invisible-text">[BR]</span></em>
+ <em><span class="marked-invisible-text">[BR]</span></em>
+ <li></span>Julia<span class="marked-text"><em><span class="marked-invisible-text">[BR]</span></em>
+ <em><span class="marked-invisible-text">[BR]</span></em>
+<em><span class="marked-invisible-text">[BR]</span></em>
+</ul><em><span class="marked-invisible-text">[BR]</span></em>
+<p>That's all.</span></pre></div><p>You have a lot of unwanted spaces and line breaks here.
+ Fortunately neither HTML nor XML is typically white-space sensitive,
+ but this amount of superfluous white-space can be annoying, and
+ needlessly increases the size of produced HTML. Of course, it is even
+ bigger problem when outputting white-space-sensitive formats.</p><p>FreeMarker provides the following tools to cope with this
+ problem:</p><ul>
+ <li>
+ <p>Tools to ignore certain white-space of the template files
+ <span class="marked-for-programmers">(parse time white-space
+ removal)</span>:</p>
+
+ <ul>
+ <li>
+ <p>White-space stripping: This feature automatically
+ ignores typical superfluous white-space around FTL tags. It
+ can be enabled or disabled on per template manner.</p>
+ </li>
+
+ <li>
+ <p>Trimmer directives: <code class="inline-code">t</code>,
+ <code class="inline-code">rt</code>, <code class="inline-code">lt</code>. With these
+ directives you can explicitly tell FreeMarker to ignore
+ certain white-space. Read <a href="ref_directive_t.html#ref.directive.t">the
+ reference</a> for more information.</p>
+ </li>
+
+ <li>
+ <p><a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code></a>
+ parameter <code class="inline-code">strip_text</code>. This removes all
+ top-level text from the template. It is useful for templates
+ that contain macro definitions only (and some other
+ non-outputting directives), because it removes the line-breaks
+ that you use between the macro definitions and between the
+ other top-level directives to improve the readability of the
+ template.</p>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <p>Tools that remove white-space from the output <span class="marked-for-programmers">(on-the-fly white-space
+ removal)</span>:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">compress</code> directive.</p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_misc_whitespace_stripping">White-space stripping</h2>
+
+
+
+
+ <p>If this feature is enabled for a template, then it
+ automatically ignores (i.e. does not print to the output) two kind
+ of typical superfluous white-space:</p>
+
+ <ul>
+ <li>
+ <p>Indentation white-space, and trailing white-space at the
+ end of the line (includes the line break) will be ignored in
+ lines that contains only FTL tags (e.g.
+ <code class="inline-code"><@myMacro/></code>, <code class="inline-code"><#if
+ <em class="code-color">...</em>></code>) and/or FTL
+ comments (e.g. <code class="inline-code"><#-- blah --></code>), apart
+ from the the ignored white-space itself. For example, if a line
+ contains only an <code class="inline-code"><#if
+ <em class="code-color">...</em>></code>, then the
+ indentation before the tag and the line break after the tag will
+ be ignored. However, if the line contains <code class="inline-code"><#if
+ <em class="code-color">...</em>>x</code>, then the
+ white-space in that line will not be ignored, because of the
+ <code class="inline-code">x</code>, as that is not FTL tag. Note that
+ according these rules, a line that contains <code class="inline-code"><#if
+ <em class="code-color">...</em>><#list
+ <em class="code-color">...</em>></code> is subject to
+ white-space ignoring, while a line that contains
+ <code class="inline-code"><#if <em class="code-color">...</em>> <#list
+ <em class="code-color">...</em>></code> is not, because the
+ white-space between the two FTL tags is embedded white-space,
+ not indentation or trailing white-space.</p>
+ </li>
+
+ <li>
+ <p>White-space sandwiched between the following directives is
+ ignored: <code class="inline-code">macro</code>, <code class="inline-code">function</code>,
+ <code class="inline-code">assign</code>, <code class="inline-code">global</code>,
+ <code class="inline-code">local</code>, <code class="inline-code">ftl</code>,
+ <code class="inline-code">import</code>, but only if there is
+ <em>only</em> white-space and/or FTL comments
+ between the directives. In practice it means that you can put
+ empty lines between macro definitions and assignments as spacing
+ for better readability, without printing needless empty lines
+ (line breaks) to the output.</p>
+ </li>
+ </ul>
+
+ <p>The output of the last example with white-space stripping
+ enabled will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"><span class="marked-text"><p>List of users:<em><span class="marked-invisible-text">[BR]</span></em>
+<ul><em><span class="marked-invisible-text">[BR]</span></em>
+ <li></span>Joe<span class="marked-text"><em><span class="marked-invisible-text">[BR]</span></em>
+ <li></span>Julia<span class="marked-text"><em><span class="marked-invisible-text">[BR]</span></em>
+</ul><em><span class="marked-invisible-text">[BR]</span></em>
+<p>That's all.</span></pre></div>
+
+ <p>This is because after stripping the template becomes the
+ following; the ignored text is not <span class="marked-text">colored</span>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><span class="marked-text"><p>List of users:<em><span class="marked-invisible-text">[BR]</span></em></span>
+<span class="marked-ftl-tag"><#assign users = [{"name":"Joe", "hidden":false},<em><span class="marked-invisible-text">[BR]</span></em>
+ {"name":"James Bond", "hidden":true},<em><span class="marked-invisible-text">[BR]</span></em>
+ {"name":"Julia", "hidden":false}]></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-text"><ul><em><span class="marked-invisible-text">[BR]</span></em></span>
+<span class="marked-ftl-tag"><#list users as user></span><em><span class="marked-invisible-text">[BR]</span></em>
+ <span class="marked-ftl-tag"><#if !user.hidden></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-text"> <li><span class="marked-interpolation">${user.name}</span><em><span class="marked-invisible-text">[BR]</span></em></span>
+ <span class="marked-ftl-tag"></#if></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-ftl-tag"></#list></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-text"></ul><em><span class="marked-invisible-text">[BR]</span></em>
+<p>That's all.</span></pre></div>
+
+ <p>White-space stripping can be enabled/disabled in per template
+ manner with the <a href="ref_directive_ftl.html#ref.directive.ftl"><code>ftl</code> directive</a>.
+ If you don't specify this with the <code class="inline-code">ftl</code> directive,
+ then white-space stripping will be enabled or disabled depending on
+ how the programmer has configured FreeMarker. The factory default is
+ white-space stripping enabled, and the programmers probably left it
+ so (<span class="marked-for-programmers">recommended</span>). <span class="marked-for-programmers">Note that enabling white-space stripping does
+ <em>not</em> degrade the performance of template
+ execution; white-space stripping is done during template
+ loading.</span></p>
+
+ <p>White-space stripping can be disabled for a single line with
+ the <a href="ref_directive_nt.html#ref.directive.nt"><code>nt</code></a>
+ directive (for No Trim).</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_30">Using compress directive</h2>
+
+
+
+
+ <p>Another solution is to use the <a href="ref_directive_compress.html#ref.directive.compress"><code>compress</code>
+ directive</a>. As opposed to white-space stripping, this works
+ directly on the generated output, not on the template. That is, it
+ will investigate the printed output on the fly, and does not
+ investigate the FTL program that creates the output. It aggressively
+ removes indentations, empty lines and repeated spaces/tabs (for more
+ information read the <a href="ref_directive_compress.html#ref.directive.compress">reference</a>). So the output
+ of:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><strong><#compress></strong>
+<#assign users = [{"name":"Joe", "hidden":false},
+ {"name":"James Bond", "hidden":true},
+ {"name":"Julia", "hidden":false}]>
+List of users:
+<#list users as user>
+ <#if !user.hidden>
+ - ${user.name}
+ </#if>
+</#list>
+That's all.
+<strong></#compress></strong></pre></div>
+
+ <p>will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">List of users:
+- Joe
+- Julia
+That's all.</pre></div>
+
+ <p>Note that <code class="inline-code">compress</code> is totally independent
+ of white-space stripping. So it is possible that the white-space of
+ template is stripped, and later the produced output is
+ <code class="inline-code">compress</code>-ed.</p>
+
+ <p>Also, by default a user-defined directve called
+ <code class="inline-code">compress</code> is available in the data-model (due to
+ backward compatibility). This is the same as the directive, except
+ that you may optionally set the <code class="inline-code">single_line</code>
+ parameter, which will remove all intervening line breaks. If you
+ replace
+ <code class="inline-code"><#compress><em class="code-color">...</em></#compress></code>
+ on the last example with <code class="inline-code"><@compress
+ single_line=true><em class="code-color">...</em></@compress></code>,
+ then you get this output:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">List of users: - Joe - Julia That's all.</pre></div>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_namespace.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_alternativesyntax.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_quickstart.html b/legacy-tests/build/test/1/dgui_quickstart.html
new file mode 100644
index 0000000..e72b9d9
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_quickstart.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-chapter">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Getting Started - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Getting Started">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_quickstart.html">
+<link rel="canonical" href="http://example.com/dgui_quickstart.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Getting Started"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_basics.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="dgui_quickstart" itemprop="headline">Getting Started</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="dgui_quickstart_basics.html" data-menu-target="dgui_quickstart_basics">Template + data-model = output</a></li><li><a class="page-menu-link" href="dgui_quickstart_datamodel.html" data-menu-target="dgui_quickstart_datamodel">The data-model at a glance</a></li><li><a class="page-menu-link" href="dgui_quickstart_template.html" data-menu-target="dgui_quickstart_template">The template at a glance</a></li></ul> </div><p>This chapter is a very rough introd [...]
+ chapters after this will go over things in much greater detail.
+ Nonetheless, once you have read this chapter, you will be able to write
+ simple but useful FreeMarker templates.</p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_basics.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_quickstart_basics.html b/legacy-tests/build/test/1/dgui_quickstart_basics.html
new file mode 100644
index 0000000..adfd96e
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_quickstart_basics.html
@@ -0,0 +1,135 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Template + data-model = output - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Template + data-model = output">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_quickstart_basics.html">
+<link rel="canonical" href="http://example.com/dgui_quickstart_basics.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Getting Started","Template + data-model = output"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_quickstart.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_datamodel.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_quickstart_basics" itemprop="headline">Template + data-model = output</h1>
+</div></div><p>Assume you need a HTML page in an e-shop application, similar to
+ this:</p>
+
+<div class="code-wrapper"><pre class="code-block code-output"><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>Welcome <strong>Big Joe</strong>!</h1>
+ <p>Our latest product:
+ <a href="<strong>products/greenmouse.html</strong>"><strong>green mouse</strong></a>!
+</body>
+</html></pre></div><p>Let's say that the user name ("Big Joe" above) should depend on
+ who the logged in Web page visitor is, and the latest product should
+ come from a database and thus it potentially changes at any moment. In
+ this situation you can't just enter the user name nor the URL and name
+ of the latest product into the HTML, you can't use static HTML.</p><p>FreeMarker's solution for this problem is using a <strong>template</strong> instead of the static HTML. The
+ template is the same as the static HTML, except that it contains some
+ instructions to FreeMarker that makes it dynamic:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><a name="example.first"></a><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>Welcome <strong>${user}</strong>!</h1>
+ <p>Our latest product:
+ <a href="<strong>${latestProduct.url}</strong>"><strong>${latestProduct.name}</strong></a>!
+</body>
+</html></pre></div><p>The template is stored on the Web server, usually just like the
+ static HTML page would be. But whenever someone visits this page,
+ FreeMarker will step in and transform the template on-the-fly to plain
+ HTML by replacing the
+ <code class="inline-code">${<em class="code-color">...</em>}</code>-s with up-to-date
+ content (e.g., replacing <code class="inline-code">${user}</code> with Big Joe or
+ whoever the visitor is) and send the result to the visitor's Web
+ browser. So the visitor's Web browser will receive something like the
+ first example HTML (i.e., plain HTML without FreeMarker instructions),
+ and it will not perceive that FreeMarker is used on the server. The
+ template file itself (which is, again, stored on the Web server) is
+ not changed during this, so the transformation will happen again and
+ again for each visiting. This ensures that the displayed information
+ is always up-to-date.</p><p>Now, you may already noticed that the template contains no
+ instructions regarding how to find out who the current visitor is, or
+ how to query the database to find out what the latest product is. It
+ seems it just already know these values. And indeed that's the case.
+ An important idea behind FreeMarker (actually, behind Web MVC) is that
+ presentation logic and "business logic" should be separated. In the
+ template you only deal with presentation issues, that is, visual
+ design issues, formatting issues. The data that will be displayed
+ (such as the user name and so on) is prepared outside FreeMarker,
+ usually by routines written in Java language or other general purpose
+ language. So the template author doesn't have to know how these values
+ are calculated. In fact, the way these values are calculated can be
+ completely changed while the templates can remain the same, and also,
+ the look of the page can be completely changed without touching
+ anything but the template. This separation can be especially useful
+ when the template authors (designers) and the programmers are
+ different individuals.</p><p>While for FreeMarker (and for the template author) it's
+ not interesting <em>how</em> the data was calculated,
+ FreeMarker still have to know <em>what</em> the actual
+ data is. All the data that the template can use is packed into the so
+ called <strong>data-model</strong>. It's created by
+ the already mentioned routines that calculate the data. As far as the
+ template author is concerned, the data-model is a tree-like structure
+ (like folders and files on your hard disk), that in this case could be
+ visualized as:</p>
+
+<div class="code-wrapper"><pre class="code-block code-data-model">(root)
+ |
+ +- <strong>user</strong> = "Big Joe"
+ |
+ +- <strong>latestProduct</strong>
+ |
+ +- <strong>url</strong> = "products/greenmouse.html"
+ |
+ +- <strong>name</strong> = "green mouse"</pre></div><p>(To prevent misunderstandings: The data-model is not a text
+ file, the above is just a visualization of a data-model for you. It's
+ from Java objects, but let that be the problem of the Java
+ programmers.)</p><p>Compare this with what you seen in the template earlier:
+ <code class="inline-code">${user}</code> and
+ <code class="inline-code">${latestProduct.name}</code>. As an analogy, the data
+ model is something like the file system of computers: the root and
+ <code class="inline-code">latestProduct</code> correspond to directories (folders)
+ and the <code class="inline-code">user</code>, <code class="inline-code">url</code> and
+ <code class="inline-code">name</code> correspond to files. <code class="inline-code">url</code>
+ and <code class="inline-code">name</code> are in the
+ <code class="inline-code">latestProduct</code> directory. So
+ <code class="inline-code">latestProduct.name</code> is like saying
+ <code class="inline-code">name</code> in the <code class="inline-code">latestProduct</code>
+ directory. But as I said, it was just a simile; there are no files or
+ directories here.</p><p>To recapitulate, a template and a data-model is needed for
+ FreeMarker to generate the output (like the HTML shown first):</p><p><span class="marked-template">Template</span> + <span class="marked-data-model">data-model</span> = <span class="marked-output">output</span></p><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_quickstart.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_datamodel.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_quickstart_datamodel.html b/legacy-tests/build/test/1/dgui_quickstart_datamodel.html
new file mode 100644
index 0000000..9414830
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_quickstart_datamodel.html
@@ -0,0 +1,185 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>The data-model at a glance - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="The data-model at a glance">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_quickstart_datamodel.html">
+<link rel="canonical" href="http://example.com/dgui_quickstart_datamodel.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Getting Started","The data-model at a glance"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_quickstart_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_template.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_quickstart_datamodel" itemprop="headline">The data-model at a glance</h1>
+</div></div><p>As you have seen, the data-model is basically a tree. This tree
+ can be arbitrarily complicated and deep, for example:</p>
+
+<div class="code-wrapper"><pre class="code-block code-data-model"><a name="example.qStart.dataModelWithHashes"></a>(root)
+ |
+ +- animals
+ | |
+ | +- mouse
+ | | |
+ | | +- size = "small"
+ | | |
+ | | +- price = 50
+ | |
+ | +- elephant
+ | | |
+ | | +- size = "large"
+ | | |
+ | | +- price = 5000
+ | |
+ | +- python
+ | |
+ | +- size = "medium"
+ | |
+ | +- price = 4999
+ |
+ +- test = "It is a test"
+ |
+ +- whatnot
+ |
+ +- because = "don't know"</pre></div><p>The variables that act as directories (the root,
+ <code class="inline-code">animals</code>, <code class="inline-code">mouse</code>,
+ <code class="inline-code">elephant</code>, <code class="inline-code">python</code>,
+ <code class="inline-code">whatnot</code>) are called <strong>hashes</strong>. Hashes store other variables (the so
+ called <a name="topic.dataModel.subVar"></a><em>subvariables</em>)
+ by a lookup name (e.g., "animals", "mouse" or "price").</p><p>The variables that store a single value
+ (<code class="inline-code">size</code>, <code class="inline-code">price</code>,
+ <code class="inline-code">test</code> and <code class="inline-code">because</code>) are called
+ <strong>scalars</strong>.</p><p><a name="topic.qStart.accessVariables"></a>When you want to
+ use a subvariable in a template, you specify its path from the root,
+ and separate the steps with dots. To access the
+ <code class="inline-code">price</code> of a <code class="inline-code">mouse</code>, you start from
+ the root and go into <code class="inline-code">animals</code>, and then go into
+ <code class="inline-code">mouse</code> then go into <code class="inline-code">price</code>. So you
+ write <code class="inline-code">animals.mouse.price</code>. When you put the special
+ <code class="inline-code">${<em class="code-color">...</em>}</code> codes around an
+ expression like this, you are telling FreeMarker to output the
+ corresponding text at that point.</p><p>There is one more important kind of variable: <strong>sequences</strong>. They are similar to hashes, but they
+ don't store names for the variables they contain. Instead, they store
+ the subvariables sequentially, and you can access them with a
+ numerical index. For example, in this data-model,
+ <code class="inline-code">animals</code> and <code class="inline-code">whatnot.fruits</code> are
+ sequences:</p>
+
+<div class="code-wrapper"><pre class="code-block code-data-model"><a name="example.qStart.dataModelWithSequences"></a>(root)
+ |
+ +- animals
+ | |
+ | +- (1st)
+ | | |
+ | | +- name = "mouse"
+ | | |
+ | | +- size = "small"
+ | | |
+ | | +- price = 50
+ | |
+ | +- (2nd)
+ | | |
+ | | +- name = "elephant"
+ | | |
+ | | +- size = "large"
+ | | |
+ | | +- price = 5000
+ | |
+ | +- (3rd)
+ | |
+ | +- name = "python"
+ | |
+ | +- size = "medium"
+ | |
+ | +- price = 4999
+ |
+ +- whatnot
+ |
+ +- fruits
+ |
+ +- (1st) = "orange"
+ |
+ +- (2nd) = "banana"</pre></div><p>To access a subvariable of a sequence you use a numerical index
+ in square brackets. Indexes start from 0 (it's a programmer tradition
+ to start with 0), thus the index of the first item is 0, the index of
+ the second item is 1, and so on. So to get the name of the first
+ animal you write <code class="inline-code">animals[0].name</code>. To get the second
+ item in <code class="inline-code">whatnot.fruits</code> (which is the string
+ <code class="inline-code">"banana"</code>) you write
+ <code class="inline-code">whatnot.fruits[1]</code>.</p><p>Scalars can further divided into these categories:</p><ul>
+ <li>
+ <p>String: Text, that is, an arbitrary sequence of characters
+ such as ''m'', ''o'', ''u'', ''s'', ''e'' above. For example the
+ <code class="inline-code">name</code>-s and <code class="inline-code">size</code>-s are
+ strings above.</p>
+ </li>
+
+ <li>
+ <p>Number: It's a numerical value, like the
+ <code class="inline-code">price</code>-s above. The string
+ <code class="inline-code">"50"</code> and the number <code class="inline-code">50</code> are
+ two totally different things in FreeMarker. The former is just a
+ sequence of two characters (which happens to be readable as a
+ number for humans), while the latter is a numerical value that you
+ can use, say, in arithmetical calculations.</p>
+ </li>
+
+ <li>
+ <p>Date/time: A date or time. Like the date an animal were
+ captured, or the time the shop opens.</p>
+ </li>
+
+ <li>
+ <p>Boolean: A true/false (yes/no, on/off, etc.) thing. Like
+ animals could have a <code class="inline-code">protected</code> subvariable,
+ which store if the animal is protected or not.</p>
+ </li>
+ </ul><p>Summary:</p><ul>
+ <li>
+ <p>The data-model can be visualized as a tree.</p>
+ </li>
+
+ <li>
+ <p>Scalars store a single value. The value can be a string or a
+ number or a date/time or a boolean.</p>
+ </li>
+
+ <li>
+ <p>Hashes are containers that store other variables and
+ associate them with a unique lookup name.</p>
+ </li>
+
+ <li>
+ <p>Sequences are containers that store other variables in an
+ ordered sequence. The stored variables can be retrieved via their
+ numerical index, starting from 0.</p>
+ </li>
+ </ul><div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_quickstart_basics.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_quickstart_template.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_quickstart_template.html b/legacy-tests/build/test/1/dgui_quickstart_template.html
new file mode 100644
index 0000000..d870d4c
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_quickstart_template.html
@@ -0,0 +1,429 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>The template at a glance - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="The template at a glance">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_quickstart_template.html">
+<link rel="canonical" href="http://example.com/dgui_quickstart_template.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","Getting Started","The template at a glance"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_quickstart_datamodel.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_quickstart_template" itemprop="headline">The template at a glance</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#autoid_7" data-menu-target="autoid_7">Examples of directives</a><ul><li><a class="page-menu-link" href="#autoid_8" data-menu-target="autoid_8">The if directive</a></li><li><a class="page-menu-link" href="#autoid_9" data-menu-target="autoid_9">The list directive</a></li><li><a class="page-menu-link" href="#autoid_10" data-menu-target="autoid_10">The include directive</a></li></ul></li><li><a class="page-menu-link" href="#autoid_11" data-menu-target [...]
+ file -- FreeMarker is not confined to HTML). When the client visits
+ that page, FreeMarker will send that HTML to the client as is. However
+ if you want that page to be more dynamic then you begin to put special
+ parts into the HTML which will be understood by FreeMarker:</p><ul>
+ <li>
+ <p><code class="inline-code">${<em class="code-color">...</em>}</code>:
+ FreeMarker will replace it in the output with the actual value of
+ the thing inside the curly brackets. They are called <strong>interpolation</strong>s. As an example see <a href="dgui_quickstart_basics.html#example.first">the very first example</a>.</p>
+ </li>
+
+ <li>
+ <p><strong>FTL tags</strong> (for FreeMarker
+ Template Language tags): FTL tags are a bit similar to HTML tags,
+ but they are instructions to FreeMarker and will not be printed to
+ the output. The name of these tags start with
+ <code class="inline-code">#</code>. (User-defined FTL tags use
+ <code class="inline-code">@</code> instead of <code class="inline-code">#</code>, but they are
+ an advanced topic.)</p>
+ </li>
+
+ <li>
+ <p><strong>Comments:</strong> Comments are
+ similar to HTML comments, but they are delimited by
+ <code class="inline-code"><#--</code> and <code class="inline-code">--></code>. Anything
+ between these delimiters and the delimiter itself will be ignored
+ by FreeMarker, and will not be written to the output.</p>
+ </li>
+ </ul><p>Anything not an FTL tag or an interpolation or comment is
+ considered as static text, and will not be interpreted by FreeMarker;
+ it is just printed to the output as is.</p><p>With FTL tags you refer to so-called <strong>directives</strong>. This is the same kind of
+ relationship as between HTML tags (e.g.:
+ <code class="inline-code"><table></code> and
+ <code class="inline-code"></table></code>) and HTML elements (e.g., the
+ <code class="inline-code">table</code> element) to which you refer to with the HTML
+ tags. (If you don't feel this difference then just take "FTL tag" and
+ "directive" as synonyms.)</p>
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_7">Examples of directives</h2>
+
+
+ <p>Though FreeMarker has far more directives, in this quick
+ overview we will only look at three of the most commonly used
+ ones.</p>
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="autoid_8">The if directive</h3>
+
+
+ <p>With the <code class="inline-code">if</code> directive you can
+ conditionally skip a section of the template. For example, assume
+ that in the <a href="dgui_quickstart_basics.html#example.first">very first
+ example</a> you want to greet your boss, Big Joe, differently
+ from other users:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><html>
+<head>
+ <title>Welcome!</title>
+</head>
+<body>
+ <h1>
+ Welcome ${user}<strong><#if user == "Big Joe"></strong>, our beloved leader<strong></#if></strong>!
+ </h1>
+ <p>Our latest product:
+ <a href="${latestProduct.url}">${latestProduct.name}</a>!
+</body>
+</html></pre></div>
+
+ <p>Here you have told FreeMarker that the '', our beloved
+ leader'' should be there only if the value of the variable
+ <code class="inline-code">user</code> is equal to the string <code class="inline-code">"Big
+ Joe"</code>. In general, things between <code class="inline-code"><#if
+ <em class="code-color">condition</em>></code> and
+ <code class="inline-code"></#if></code> tags are skipped if
+ <code class="inline-code"><em class="code-color">condition</em></code> is false
+ (the boolean value).</p>
+
+ <p>Let's detail the
+ <code class="inline-code"><em class="code-color">condition</em></code> used here:
+ The <code class="inline-code">==</code> is an operator that tests if the values
+ at its left and right side are equivalent, and the results is a
+ boolean value, true or false accordingly. On the left side of
+ <code class="inline-code">==</code> I have <a href="dgui_quickstart_datamodel.html#topic.qStart.accessVariables">referenced a
+ variable</a> with the syntax that should be already familiar;
+ this will be replaced with the value of the variable. In general,
+ unquoted words inside directives or interpolations are treated as
+ references to variables. On the right side I have specified a
+ literal string. Literal strings in templates must
+ <em>always</em> be put inside quotation marks.</p>
+
+ <p>This will print "Pythons are free today!" if their price is
+ 0:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if animals.python.price == <strong>0</strong>>
+ Pythons are free today!
+</#if></pre></div>
+
+ <p>Similarly as earlier when a string was specified directly,
+ here a number is specified directly (<code class="inline-code">0</code>). Note
+ that the number is <em>not</em> quoted. If you quoted
+ it (<code class="inline-code">"0"</code>), FreeMarker were misinterpret it as a
+ string literal.</p>
+
+ <p>This will print "Pythons are not free today!" if their price
+ is not 0:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if animals.python.price <strong>!=</strong> 0>
+ Pythons are not free today!
+</#if></pre></div>
+
+ <p>As you may have guessed, <code class="inline-code">!=</code> means not
+ equivalent.</p>
+
+ <p>You can write things like this too (using <a href="dgui_quickstart_datamodel.html#example.qStart.dataModelWithHashes">the data-model used
+ to demonstrate hashes</a>):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if <strong>animals.python.price < animals.elephant.price</strong>>
+ Pythons are cheaper than elephants today.
+</#if></pre></div>
+
+ <p>With the <code class="inline-code"><#else></code> tag you can
+ specify what to do if the condition is false. For example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if animals.python.price < animals.elephant.price>
+ Pythons are cheaper than elephants today.
+<strong><#else></strong>
+ Pythons are not cheaper than elephants today.
+</#if></pre></div>
+
+ <p>This prints ''Pythons are cheaper than elephants today.'' if
+ the price of python is less than the price of elephant, or else it
+ prints ''Pythons are not cheaper than elephants today.''</p>
+
+ <p>If you have a variable with boolean value (a true/false
+ thing) then you can use it directly as the
+ <code class="inline-code"><em class="code-color">condition</em></code> of
+ <code class="inline-code">if</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if animals.python.protected>
+ Warning! Pythons are protected animals!
+</#if></pre></div>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="autoid_9">The list directive</h3>
+
+
+ <p>This is useful when you want to list something. For example
+ if you merge this template with the <a href="dgui_quickstart_datamodel.html#example.qStart.dataModelWithSequences">data-model I used
+ earlier to demonstrate sequences</a>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><p>We have these animals:
+<table border=1>
+ <tr><th>Name<th>Price
+ <strong><#list animals as being></strong>
+ <tr><td>${<strong>being</strong>.name}<td>${<strong>being</strong>.price} Euros
+ <strong></#list></strong>
+</table></pre></div>
+
+ <p>then the output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"><p>We have these animals:
+<table border=1>
+ <tr><th>Name<th>Price
+ <strong><tr><td>mouse<td>50 Euros
+ <tr><td>elephant<td>5000 Euros
+ <tr><td>python<td>4999 Euros</strong>
+</table></pre></div>
+
+ <p>The generic format of the <code class="inline-code">list</code> directive
+ is:</p>
+
+ <p><code class="inline-code"><#list <em class="code-color">sequence</em> as
+ <em class="code-color">loopVariable</em>><em class="code-color">repeatThis</em></#list></code></p>
+
+ <p>The <code class="inline-code"><em class="code-color">repeatThis</em></code>
+ part will be repeated for each item in the sequence that you have
+ given with <code class="inline-code"><em class="code-color">sequence</em></code>,
+ one after the other, starting from the first item. In all
+ repetitions
+ <code class="inline-code"><em class="code-color">loopVariable</em></code> will
+ hold the value of the current item. This variable exists only
+ between the <code class="inline-code"><#list ...></code> and
+ <code class="inline-code"></#list></code> tags.</p>
+
+ <p>As another example, we list the fruits of that example data
+ model:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><p>And BTW we have these fruits:
+<ul>
+<strong><#list whatnot.fruits as fruit></strong>
+ <li>${fruit}
+<strong></#list></strong>
+<ul></pre></div>
+
+ <p>The <code class="inline-code">whatnot.fruits</code> expression should be
+ familiar to you; it <a href="dgui_quickstart_datamodel.html#topic.qStart.accessVariables">references a variable in
+ the data-model</a>.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="autoid_10">The include directive</h3>
+
+
+ <p>With the <code class="inline-code">include</code> directive you can insert
+ the content of another file into the template.</p>
+
+ <p>Suppose you have to show the same copyright notice on
+ several pages. You can create a file that contains the copyright
+ notice only, and insert that file everywhere where you need that
+ copyright notice. Say, you store this copyright notice in
+ <code class="inline-code">copyright_footer.html</code>:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><hr>
+<i>
+Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
+<br>
+All Rights Reserved.
+</i></pre></div>
+
+ <p>Whenever you need that file you simply insert it with the
+ <code class="inline-code">include</code> directive:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><html>
+<head>
+ <title>Test page</title>
+</head>
+<body>
+ <h1>Test page</h1>
+ <p>Blah blah...
+<strong><#include "/copyright_footer.html"></strong>
+</body>
+</html></pre></div>
+
+ <p>and the output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"><html>
+<head>
+ <title>Test page</title>
+</head>
+<body>
+ <h1>Test page</h1>
+ <p>Blah blah...
+<strong><hr>
+<i>
+Copyright (c) 2000 <a href="http://www.acmee.com">Acmee Inc</a>,
+<br>
+All Rights Reserved.
+</i></strong>
+</body>
+</html></pre></div>
+
+ <p>If you change the <code class="inline-code">copyright_footer.html</code>,
+ then the visitor will see the new copyright notice on all
+ pages.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_11">Using directives together</h2>
+
+
+ <p>You can use directives as many times on a page as you want,
+ and you can nest directives into each other similarly as you can
+ nest HTML elements into each other. For example this will list the
+ animals and print the name of large animals with bigger font:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><p>We have these animals:
+<table border=1>
+ <tr><th>Name<th>Price
+ <strong><#list animals as being></strong>
+ <tr>
+ <td>
+ <strong><#if being.size == "large"></strong><font size="+1"><strong></#if></strong>
+ ${being.name}
+ <strong><#if being.size == "large"></strong></font><strong></#if></strong>
+ <td>${being.price} Euros
+ <strong></#list></strong>
+</table></pre></div>
+
+ <p>Note that since FreeMarker does not interpret text outside FTL
+ tags, interpolations and comments, it doesn't see the above
+ <code class="inline-code">font</code> tags as badly nested ones.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="autoid_12">Dealing with missing variables</h2>
+
+
+ <p>In practice the data-model often has variables that are
+ optional (i.e., sometimes missing). To spot some typical human
+ mistakes, FreeMarker doesn't tolerate the referring to missing
+ variables unless you tell them explicitly what to do if the variable
+ is missing. Here we will show the two most typical ways of doing
+ that.</p>
+
+ <p><span class="marked-for-programmers">Note for programmers: A
+ non-existent variable and a variable with <code class="inline-code">null</code>
+ value is the same for FreeMarker, so the "missing" term used here
+ covers both cases.</span></p>
+
+ <p>Wherever you refer to a variable, you can specify a default
+ value for the case the variable is missing, by followin the variable
+ name with a <code class="inline-code">!</code> and the default value. Like in the
+ following example, when <code class="inline-code">user</code> is missing from data
+ model, the template will behave like if <code class="inline-code">user</code>'s
+ value were the string <code class="inline-code">"Anonymous"</code>. (When
+ <code class="inline-code">user</code> isn't missing, this template behaves exactly
+ like if <code class="inline-code">!"Anonymous"</code> were not there):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><h1>Welcome ${user<strong>!"Anonymous"</strong>}!</h1></pre></div>
+
+ <p>You can ask whether a variable isn't missing by putting
+ <code class="inline-code">??</code> after its name. Combining this with the
+ already introduced <code class="inline-code">if</code> directive you can skip the
+ whole greeting if the <code class="inline-code">user</code> variable is
+ missing:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if <strong>user??</strong>><h1>Welcome ${user}!</h1></#if></pre></div>
+
+ <p>Regarding variable accessing with multiple steps, like
+ <code class="inline-code">animals.python.price</code>, writing
+ <code class="inline-code">animals.python.price!0</code> is correct only if
+ <code class="inline-code">animals.python</code> is never missing and only the last
+ subvariable, <code class="inline-code">price</code>, is possibly missing (in which
+ case here we assume it's <code class="inline-code">0</code>). If
+ <code class="inline-code">animals</code> or <code class="inline-code">python</code> is missing,
+ the template processing will stop with an "undefined variable"
+ error. To prevent that, you have to write
+ <code class="inline-code">(animals.python.price)!0</code>. In that case the
+ expression will be <code class="inline-code">0</code> even if
+ <code class="inline-code">animals</code> or <code class="inline-code">python</code> is missing.
+ Same logic goes for <code class="inline-code">??</code>;
+ <code class="inline-code">animals.python.price??</code> versus
+ <code class="inline-code">(animals.python.price)??</code>.</p>
+ <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_quickstart_datamodel.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_datamodel.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_template.html b/legacy-tests/build/test/1/dgui_template.html
new file mode 100644
index 0000000..e9d42d1
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_template.html
@@ -0,0 +1,51 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-chapter">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>The Template - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="The Template">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_template.html">
+<link rel="canonical" href="http://example.com/dgui_template.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","The Template"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_datamodel_types.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_overallstructure.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-chapter" id="dgui_template" itemprop="headline">The Template</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Section Contents</div>
+<ul><li><a class="page-menu-link" href="dgui_template_overallstructure.html" data-menu-target="dgui_template_overallstructure">Overall structure</a></li><li><a class="page-menu-link" href="dgui_template_directives.html" data-menu-target="dgui_template_directives">Directives</a></li><li><a class="page-menu-link" href="dgui_template_exp.html" data-menu-target="dgui_template_exp">Expressions</a></li><li><a class="page-menu-link" href="dgui_template_valueinsertion.html" data-menu-target="dgu [...]
+ <strong class="callout-label">Note:</strong>
+
+ <p>It is assumed that you have already read the <a href="dgui_quickstart.html">Getting Started</a> and the <a href="dgui_datamodel.html">Values, Types</a>
+ chapter.</p>
+ </div>
+<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_datamodel_types.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_overallstructure.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_template_directives.html b/legacy-tests/build/test/1/dgui_template_directives.html
new file mode 100644
index 0000000..b0a07e7
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_template_directives.html
@@ -0,0 +1,127 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Directives - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Directives">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_template_directives.html">
+<link rel="canonical" href="http://example.com/dgui_template_directives.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","The Template","Directives"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_template_overallstructure.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_exp.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_template_directives" itemprop="headline">Directives</h1>
+</div></div><a name="term.designer.directive"></a><p>You use FTL tags to call <strong>directives</strong>. In the example you have called the
+ <code class="inline-code">list</code> directive. Syntactically you have done it with
+ two tags: <code class="inline-code"><#list animals as being></code> and
+ <code class="inline-code"></#list></code>.</p><p>There are two kind of FTL tags:</p><ul>
+ <li>
+ <p>Start-tag:
+ <code class="inline-code"><#<em class="code-color">directivename</em>
+ <em class="code-color">parameters</em>></code></p>
+ </li>
+
+ <li>
+ <p>End-tag:
+ <code class="inline-code"></#<em class="code-color">directivename</em>></code></p>
+ </li>
+ </ul><p>This is similar to HTML or XML syntax, except that the tag name
+ starts with <code class="inline-code">#</code>. If the directive doesn't have nested
+ content (content between the start-tag and the end-tag), you must use
+ the start-tag with no end-tag. For example you write <code class="inline-code"><#if
+ <em class="code-color">something</em>><em class="code-color">...</em></#if></code>,
+ but just <code class="inline-code"><#include
+ <em class="code-color">something</em>></code> as FreeMarker knows
+ that the <code class="inline-code">include</code> directive can't have nested
+ content.</p><p>The format of the
+ <code class="inline-code"><em class="code-color">parameters</em></code> depends on
+ the
+ <code class="inline-code"><em class="code-color">directivename</em></code>.</p><p>In fact there are two types of directives: <a href="gloss.html#gloss.predefinedDirective">predefined directives</a> and
+ <a href="gloss.html#gloss.userDefinedDirective">user-defined
+ directives</a>. For user-defined directives you use
+ <code class="inline-code">@</code> instead of <code class="inline-code">#</code>, for example
+ <code class="inline-code"><@mydirective
+ <em class="code-color">parameters</em>><em class="code-color">...</em></@mydirective></code>.
+ Further difference is that if the directive has no nested content, you
+ must use a tag like <code class="inline-code"><@mydirective
+ <em class="code-color">parameters</em> /></code>, similarly as in
+ XML (e.g. <code class="inline-code"><img <em class="code-color">...</em>
+ /></code>). But user-defined directives is an advanced topic
+ that will be discussed <a href="dgui_misc_userdefdir.html">later</a>.</p><p>FTL tags, like HTML tags, must be properly nested. So the code
+ below is wrong, as the <code class="inline-code">if</code> directive is both inside
+ and outside of the nested content of the <code class="inline-code">list</code>
+ directive:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><ul>
+<strong><#list animals as being></strong>
+ <li>${being.name} for ${being.price} Euros
+ <strong><#if user == "Big Joe"></strong>
+ (except for you)
+<strong></#list></strong> <#-- WRONG! The "if" has to be closed first. -->
+<strong></#if></strong>
+</ul></pre></div><p>Note that FreeMarker doesn't care about the nesting of HTML
+ tags, only about the nesting of FTL tags. It just sees HTML as flat
+ text, it doesn't interpret it in any way.</p><p>If you try to use a non-existing directive (e.g., you mistype
+ the directive name), FreeMarker will decline to use the template and
+ produce an error message.</p><p>FreeMarker ignores superfluous <a href="gloss.html#gloss.whiteSpace">white-space</a> inside FTL tags. So you
+ can write this:</p>
+
+<div class="code-wrapper"><pre class="code-block code-template"><span class="marked-text"><span class="marked-ftl-tag"><#list<em><span class="marked-invisible-text">[BR]</span></em>
+ animals as<em><span class="marked-invisible-text">[BR]</span></em>
+ being<em><span class="marked-invisible-text">[BR]</span></em>
+></span><em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-interpolation">${being.name}</span> for <span class="marked-interpolation">${being.price}</span> Euros<em><span class="marked-invisible-text">[BR]</span></em>
+<span class="marked-ftl-tag"></#list ></span></span></pre></div><p>You may not, however, insert white-space between the
+ <code class="inline-code"><</code> or <code class="inline-code"></</code> and the directive
+ name.</p><p>The complete list and description of all directives can be found
+ in the <a href="ref_directives.html">Reference/Directive Reference</a> (but I recommend that you
+ look at the chapter about expressions first).</p> <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>FreeMarker can be configured to use <code class="inline-code">[</code> and
+ <code class="inline-code">]</code> instead of <code class="inline-code"><</code> and
+ <code class="inline-code">></code> in the FTL tags and FTL comments, like
+ <code class="inline-code">[#if user == "Big
+ Joe"]<em class="code-color">...</em>[/#if]</code>. For more
+ information read: <a href="dgui_misc_alternativesyntax.html">Miscellaneous/Alternative (square bracket) syntax</a>.</p>
+ </div>
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>FreeMarker can be configured so that it understands predefined
+ directives without <code class="inline-code">#</code> (like <code class="inline-code"><if user
+ == "Big
+ Joe"><em class="code-color">...</em></if></code>).
+ However we don't recommend the usage of this mode. For more
+ information read: <a href="ref_depr_oldsyntax.html">Reference/Deprecated FTL constructs/Old FTL syntax</a></p>
+ </div>
+<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_template_overallstructure.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_exp.html"><span>Next</span></a></div></div></div></div> </div>
+ </div>
+<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"></div><div class="col-right"><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
+Last generated:
+<time itemprop="dateModified" datetime="2020-07-09T23:48:39Z" title="Thursday, July 9, 2020 11:48:39 PM GMT">2020-07-09 23:48:39 GMT</time> </p>
+<p class="copyright">
+© <span itemprop="copyrightYear">1999</span>–2020
+<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
+</div></div></div></body>
+</html>
diff --git a/legacy-tests/build/test/1/dgui_template_exp.html b/legacy-tests/build/test/1/dgui_template_exp.html
new file mode 100644
index 0000000..ea6f403
--- /dev/null
+++ b/legacy-tests/build/test/1/dgui_template_exp.html
@@ -0,0 +1,1944 @@
+<!doctype html>
+<!-- Generated by FreeMarker/Docgen from DocBook -->
+<html lang="en" class="page-type-section">
+<head prefix="og: http://ogp.me/ns#">
+<meta charset="utf-8">
+<title>Expressions - FreeMarker Manual</title>
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<meta name="format-detection" content="telephone=no">
+<meta property="og:site_name" content="FreeMarker Manual">
+<meta property="og:title" content="Expressions">
+<meta property="og:locale" content="en_US">
+<meta property="og:url" content="http://example.com/dgui_template_exp.html">
+<link rel="canonical" href="http://example.com/dgui_template_exp.html">
+<link rel="icon" href="favicon.png" type="image/png">
+<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338519184">
+</head>
+<body itemscope itemtype="https://schema.org/Code">
+ <meta itemprop="url" content="http://example.com/">
+ <meta itemprop="name" content="FreeMarker Manual">
+
+ <!--[if lte IE 9]>
+ <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
+ <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
+</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">FreeMarker Manual [...]
+ <div class="content-wrapper">
+ <div id="table-of-contents-wrapper" class="col-left">
+ <script>var breadcrumb = ["FreeMarker Manual","Template Author\'s Guide","The Template","Expressions"];</script>
+ <script src="toc.js?1594338519184"></script>
+ <script src="docgen-resources/main.min.js?1594338519184"></script>
+ </div>
+<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_template_directives.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_template_valueinsertion.html"><span>Next</span></a></div><div class="title-wrapper">
+<h1 class="content-header header-section1" id="dgui_template_exp" itemprop="headline">Expressions</h1>
+</div></div><div class="page-menu">
+<div class="page-menu-title">Page Contents</div>
+<ul><li><a class="page-menu-link" href="#exp_cheatsheet" data-menu-target="exp_cheatsheet">Quick overview (cheat sheet)</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct" data-menu-target="dgui_template_exp_direct">Specify values directly</a><ul><li><a class="page-menu-link" href="#dgui_template_exp_direct_string" data-menu-target="dgui_template_exp_direct_string">Strings</a></li><li><a class="page-menu-link" href="#dgui_template_exp_direct_number" data-menu-target="d [...]
+ parameters you can use variables or more complex expressions. For
+ example, if x is the number 8 and y is 5, the value of <code class="inline-code">(x +
+ y)/2</code> resolves to the numerical value 6.5.</p><p>Before we go into details, let's see some concrete
+ examples:</p><ul>
+ <li>
+ <p>When you supply value for interpolations: The usage of
+ interpolations is
+ <code class="inline-code">${<em class="code-color">expression</em>}</code> where
+ expression gives the value you want to insert into the output as
+ text. So <code class="inline-code">${(5 + 8)/2}</code> prints ``6.5'' to the
+ output (or possibly ``6,5'' if the language of your output is not
+ US English).</p>
+ </li>
+
+ <li>
+ <p>When you supply a value for the directive parameter: You
+ have already seen the <code class="inline-code">if</code> directive in the
+ Getting Started section. The syntax of this directive is:
+ <code class="inline-code"><#if
+ <em class="code-color">expression</em>><em class="code-color">...</em></#if></code>.
+ The expression here must evaluate to a boolean value. For example
+ in <code class="inline-code"><#if 2 < 3></code> the <code class="inline-code">2 <
+ 3</code> (2 is less than 3) is an expression which evaluates to
+ <code class="inline-code">true</code>.</p>
+ </li>
+ </ul>
+
+
+
+
+<h2 class="content-header header-section2" id="exp_cheatsheet">Quick overview (cheat sheet)</h2>
+
+
+ <p>This is a reminder for those of you who already know
+ FreeMarker or are just experienced programmers:</p>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_direct">Specify values
+ directly</a>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_direct_string">Strings</a>:
+ <code class="inline-code">"Foo"</code> or <code class="inline-code">'Foo'</code> or
+ <code class="inline-code">"It's \"quoted\""</code> or
+ <code class="inline-code">r"C:\raw\string"</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_direct_number">Numbers</a>:
+ <code class="inline-code">123.45</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_direct_boolean">Booleans</a>:
+ <code class="inline-code">true</code>, <code class="inline-code">false</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_direct_seuqence">Sequences</a>:
+ <code class="inline-code">["foo", "bar", 123.45]</code>,
+ <code class="inline-code">1..100</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_direct_hash">Hashes</a>:
+ <code class="inline-code">{"name":"green mouse",
+ "price":150}</code>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_var">Retrieving
+ variables</a>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_var_toplevel">Top-level
+ variables</a>: <code class="inline-code">user</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_var_hash">Retrieving
+ data from a hash</a>: <code class="inline-code">user.name</code>,
+ <code class="inline-code">user["name"]</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_var_sequence">Retrieving data
+ from a sequence</a>:
+ <code class="inline-code">products[5]</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_var_special">Special
+ variable</a>: <code class="inline-code">.main</code>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_stringop">String
+ operations</a>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_stringop_interpolation">Interpolation
+ (or concatenation)</a>:
+ <code class="inline-code">"Hello ${user}!"</code> (or
+ <code class="inline-code">"Free" + "Marker"</code>)
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_get_character">Getting a
+ character</a>: <code class="inline-code">name[0]</code>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_sequenceop">Sequence
+ operations</a>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_sequenceop_cat">Concatenation</a>:
+ <code class="inline-code">users + ["guest"]</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_seqenceop_slice">Sequence
+ slice</a>: <code class="inline-code">products[10..19]</code> or
+ <code class="inline-code">products[5..]</code>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_hashop">Hash
+ operations</a>
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_hashop_cat">Concatenation</a>:
+ <code class="inline-code">passwords + {"joe":"secret42"}</code>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_arit">Arithmetical
+ calculations</a>: <code class="inline-code">(x * 1.5 + 10) / 2 - y %
+ 100</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_comparison">Comparison</a>:
+ <code class="inline-code">x == y</code>, <code class="inline-code">x != y</code>,
+ <code class="inline-code">x < y</code>, <code class="inline-code">x > y</code>,
+ <code class="inline-code">x >= y</code>, <code class="inline-code">x <= y</code>,
+ <code class="inline-code">x &lt; y</code>, ...etc.
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_logicalop">Logical
+ operations</a>: <code class="inline-code">!registered && (firstVisit
+ || fromEurope)</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_builtin">Built-ins</a>:
+ <code class="inline-code">name?upper_case</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_methodcall">Method
+ call</a>: <code class="inline-code">repeat("What", 3)</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_missing">Missing value
+ handler operators</a>:
+
+ <ul>
+ <li>
+ <a href="#dgui_template_exp_missing_default">Default
+ value</a>: <code class="inline-code">name!"unknown"</code> or
+ <code class="inline-code">(user.name)!"unknown"</code> or
+ <code class="inline-code">name!</code> or
+ <code class="inline-code">(user.name)!</code>
+ </li>
+
+ <li>
+ <a href="#dgui_template_exp_missing_test">Missing
+ value test</a>: <code class="inline-code">name??</code> or
+ <code class="inline-code">(user.name)??</code>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>See also: <a href="#dgui_template_exp_precedence">Operator
+ precedence</a></p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_direct">Specify values directly</h2>
+
+
+
+
+
+
+ <p>Often you want to specify a value directly and not as a result
+ of some calculations.</p>
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_direct_string">Strings</h3>
+
+
+
+
+ <p>To specify a string value directly you give the text in
+ quotation marks, e.g.: <code class="inline-code">"some text"</code> or in
+ apostrophe-quote, e.g. <code class="inline-code">'some text'</code>. The two
+ forms are equivalent. If the text itself contains the character
+ used for the quoting (either <code class="inline-code">"</code> or
+ <code class="inline-code">'</code>) or backslashes, you have to precede them
+ with a backslash; this is called escaping. You can type any other
+ character, including <a href="gloss.html#gloss.lineBreak">line
+ breaks</a>, in the text directly. Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${"It's \"quoted\" and
+this is a backslash: \\"}
+
+${'It\'s "quoted" and
+this is a backslash: \\'}</pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">It's "quoted" and
+this is a backslash: \
+
+It's "quoted" and
+this is a backslash: \</pre></div>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>Of course, you could simply type the above text into the
+ template, without using
+ <code class="inline-code">${<em class="code-color">...</em>}</code>. But we do
+ it here just for the sake of example, to demonstrate
+ expressions.</p>
+ </div>
+
+
+ <a name="topic.escapeSequence"></a>
+
+
+
+ <p>This is the list of all supported escape sequences. All
+ other usage of backlash in string literals is an error and any
+ attempt to use the template will fail.</p>
+
+ <div class="table-responsive">
+ <table class="table">
+
+ <thead>
+ <tr>
+ <th>Escape sequence</th>
+
+
+ <th>Meaning</th>
+
+ </tr>
+
+ </thead>
+
+
+ <tbody>
+ <tr>
+ <td><code class="inline-code">\"</code></td>
+
+
+ <td>Quotation mark (u0022)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\'</code></td>
+
+
+ <td>Apostrophe (a.k.a. apostrophe-quote) (u0027)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\\</code></td>
+
+
+ <td>Back slash (u005C)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\n</code></td>
+
+
+ <td>Line feed (u000A)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\r</code></td>
+
+
+ <td>Carriage return (u000D)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\t</code></td>
+
+
+ <td>Horizontal tabulation (a.k.a. tab) (u0009)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\b</code></td>
+
+
+ <td>Backspace (u0008)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\f</code></td>
+
+
+ <td>Form feed (u000C)</td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\l</code></td>
+
+
+ <td>Less-than sign: <code class="inline-code"><</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\g</code></td>
+
+
+ <td>Greater-than sign: <code class="inline-code">></code></td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\a</code></td>
+
+
+ <td>Ampersand: <code class="inline-code">&</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td><code class="inline-code">\x<em class="code-color">Code</em></code></td>
+
+
+ <td>Character given with its hexadecimal <a href="gloss.html#gloss.unicode">Unicode</a> code (<a href="gloss.html#gloss.UCS">UCS</a> code)</td>
+
+ </tr>
+
+ </tbody>
+
+ </table>
+ </div>
+
+
+ <p>The <code class="inline-code"><em class="code-color">Code</em></code> after
+ the <code class="inline-code">\x</code> is 1 to 4 hexadecimal digits. For
+ example this all put a copyright sign into the string:
+ <code class="inline-code">"\xA9 1999-2001"</code>,
+ <code class="inline-code">"\x0A9 1999-2001"</code>,
+ <code class="inline-code">"\x00A9 1999-2001"</code>. When the character directly
+ after the last hexadecimal digit can be interpreted as hexadecimal
+ digit, you must use all 4 digits or else FreeMarker will be
+ confused.</p>
+
+ <p>Note that the character sequence <code class="inline-code">${</code> (and
+ <code class="inline-code">#{</code>) has special meaning. It's used to insert
+ the value of expressions (typically: the value of variables, as in
+ <code class="inline-code">"Hello ${user}!"</code>). This will be explained <a href="#dgui_template_exp_stringop_interpolation">later</a>.
+ If you want to print <code class="inline-code">${</code>, you should use raw
+ string literals as explained below.</p>
+
+
+
+ <p>A special kind of string literals is the raw string
+ literals. In raw string literals, backslash and
+ <code class="inline-code">${</code> have no special meaning, they are considered
+ as plain characters. To indicate that a string literal is a raw
+ string literal, you have to put an <code class="inline-code">r</code> directly
+ before the opening quotation mark or apostrophe-quote.
+ Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${r"${foo}"}
+${r"C:\foo\bar"}</pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">${foo}
+C:\foo\bar</pre></div>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_direct_number">Numbers</h3>
+
+
+
+
+ <p>To specify a numerical value directly you type the number
+ without quotation marks. You have to use the dot as your decimal
+ separator and must not use any grouping separator symbols. You can
+ use <code class="inline-code">-</code> or <code class="inline-code">+</code> to indicate the
+ sign (<code class="inline-code">+</code> is redundant). Scientific notation is
+ not yet supported (so <code class="inline-code">1E3</code> is wrong). Also, you
+ cannot omit the 0 before the decimal separator (so
+ <code class="inline-code">.5</code> is wrong).</p>
+
+ <p>Examples of valid number literals: <code class="inline-code">0.08</code>,
+ <code class="inline-code">-5.013</code>, <code class="inline-code">8</code>,
+ <code class="inline-code">008</code>, <code class="inline-code">11</code>,
+ <code class="inline-code">+11</code></p>
+
+ <p>Note that numerical literals like <code class="inline-code">08</code>,
+ <code class="inline-code">+8</code>, <code class="inline-code">8.00</code> and
+ <code class="inline-code">8</code> are totally equivalent as they all symbolize
+ the number eight. Thus, <code class="inline-code">${08}</code>,
+ <code class="inline-code">${+8}</code>, <code class="inline-code">${8.00}</code> and
+ <code class="inline-code">${8}</code> will all print exactly same.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_direct_boolean">Booleans</h3>
+
+
+
+
+
+
+ <p>To specify a boolean value you write <code class="inline-code">true</code>
+ or <code class="inline-code">false</code>. Don't use quotation marks.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_direct_seuqence">Sequences</h3>
+
+
+
+
+
+
+
+
+
+
+ <p>To specify a literal sequence, you list the <a href="dgui_quickstart_datamodel.html#topic.dataModel.subVar">subvariables</a> separated by
+ commas, and put the whole list into square brackets. For
+ example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#list <strong>["winter", "spring", "summer", "autumn"]</strong> as x>
+${x}
+</#list></pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">winter
+spring
+summer
+autumn
+ </pre></div>
+
+ <p>The items in the list are expressions, so you can do this
+ for example: <code class="inline-code">[2 + 2, [1, 2, 3, 4], "whatnot"]</code>.
+ Here the first subvariable will be the number 4, the second will
+ be another sequence, and the third subvariable will be the string
+ "whatnot".</p>
+
+ <p>You can define sequences that store a numerical range with
+ <code class="inline-code"><em class="code-color">start</em>..<em class="code-color">end</em></code>,
+ where <code class="inline-code"><em class="code-color">start</em></code> and
+ <code class="inline-code"><em class="code-color">end</em></code> are expressions
+ that resolve to numerical values. For example
+ <code class="inline-code">2..5</code> is the same as <code class="inline-code">[2, 3, 4,
+ 5]</code>, but the former is much more efficient (occupies less
+ memory and faster). Note that the square brackets are missing. You
+ can define decreasing numerical ranges too, e.g.:
+ <code class="inline-code">5..2</code>. (Furthermore, you can omit the
+ <code class="inline-code"><em class="code-color">end</em></code>, for example
+ <code class="inline-code">5..</code>, in which case the sequence will contain 5,
+ 6, 7, 8, ...etc up to the infinity.)</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_direct_hash">Hashes</h3>
+
+
+
+
+
+
+ <p>To specify a hash in a template, you list the key/value
+ pairs separated by commas, and put the list into curly brackets.
+ The key and value within a key/value pair are separated with a
+ colon. Here is an example: <code class="inline-code">{"name":"green mouse",
+ "price":150}</code>. Note that both the names and the values
+ are expressions. However, the lookup names must be strings.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_var">Retrieving variables</h2>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_var_toplevel">Top-level variables</h3>
+
+
+
+
+ <p>To access a top-level variable, you simply use the variable
+ name. For example, the expression <code class="inline-code">user</code> will
+ evaluate to the value of variable stored with name ``user'' in the
+ root. So this will print what you store there:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${user}</pre></div>
+
+ <p>If there is no such top-level variable, then an error will
+ result when FreeMarker tries to evaluate the expression, and it
+ aborts template processing (unless programmers has configured
+ FreeMarker differently).</p>
+
+ <p>In this expression the variable name can contain only
+ letters (including non-Latin letters), digits (including non-Latin
+ digits), underline (_), dollar ($), at sign (@) and hash (#).
+ Furthermore, the name must not start with digit.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_var_hash">Retrieving data from a hash</h3>
+
+
+
+
+
+
+ <p>If we already have a hash as a result of an expression, then
+ we can get its subvariable with a dot and the name of the
+ subvariable. Assume that we have this data-model:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-data-model">(root)
+ |
+ +- book
+ | |
+ | +- title = "Breeding green mouses"
+ | |
+ | +- author
+ | |
+ | +- name = "Julia Smith"
+ | |
+ | +- info = "Biologist, 1923-1985, Canada"
+ |
+ +- test = "title"</pre></div>
+
+ <p>Now we can read the <code class="inline-code">title</code> with
+ <code class="inline-code">book.title</code>, since the book expression will
+ return a hash (as explained in the last chapter). Applying this
+ logic further, we can read the name of the author with this
+ expression: <code class="inline-code">book.author.name</code>.</p>
+
+ <p>There is an alternative syntax if we want to give the
+ subvariable name with an expression:
+ <code class="inline-code">book["title"]</code>. In the square brackets you can
+ give any expression as long as it evaluates to a string. So with
+ this data-model you can also read the title with
+ <code class="inline-code">book[test]</code>. More examples; these are all
+ equivalent: <code class="inline-code">book.author.name</code>,
+ <code class="inline-code">book["author"].name</code>,
+ <code class="inline-code">book.author.["name"]</code>,
+ <code class="inline-code">book["author"]["name"]</code>.</p>
+
+ <p>When you use the dot syntax, the same restrictions apply
+ regarding the variable name as with top-level variables (name can
+ contain only letters, digits, _, $, @, etc.). There are no such
+ restrictions when you use the square bracket syntax, since the
+ name is the result of an arbitrary expression. (Note, that to help
+ the FreeMarker XML support, if the subvariable name is
+ <code class="inline-code">*</code> (asterisk) or <code class="inline-code">**</code>, then you
+ do not have to use square bracket syntax.)</p>
+
+ <p>As with the top-level variables, trying to access a
+ non-existent subvariable causes an error and aborts the processing
+ of the template (unless programmers has configured FreeMarker
+ differently).</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_var_sequence">Retrieving data from a sequence</h3>
+
+
+
+
+
+
+ <p>This is the same as for hashes, but you can use the square
+ bracket syntax only, and the expression in the brackets must
+ evaluate to a number, not a string. For example to get the name of
+ the first animal of the <a href="dgui_datamodel_basics.html#example.stdDataModel">example data-model</a> (remember
+ that the number of the first item is 0, not 1):
+ <code class="inline-code">animals[0].name</code></p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_var_special">Special variables</h3>
+
+
+
+
+ <p>Special variables are variables defined by the FreeMarker
+ engine itself. To access them, you use the
+ <code class="inline-code">.<em class="code-color">variable_name</em></code>
+ syntax.</p>
+
+ <p>Normally you don't need to use special variables. They are
+ for expert users. The complete list of special variables can be
+ found in the <a href="ref_specvar.html">reference</a>.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_stringop">String operations</h2>
+
+
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_stringop_interpolation">Interpolation (or concatenation)</h3>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <p>If you want to insert the value of an expression into a
+ string, you can use
+ <code class="inline-code">${<em class="code-color">...</em>}</code> (and
+ <code class="inline-code">#{<em class="code-color">...</em>}</code>) in string
+ literals. <code class="inline-code">${<em class="code-color">...</em>}</code>
+ behaves similarly as in <span class="marked-text">text</span>
+ sections. For example (assume that user is ``Big Joe''):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${"Hello ${user}!"}
+${"${user}${user}${user}${user}"}</pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">Hello Big Joe!
+Big JoeBig JoeBig JoeBig Joe</pre></div>
+
+ <p>Alternatively, you can use the <code class="inline-code">+</code> operator
+ to achieve similar result. This is the old method, and it is
+ called string concatenation. Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${"Hello " + user + "!"}
+${user + user + user + user}</pre></div>
+
+ <p>This will print the same as the example with the
+ <code class="inline-code">${<em class="code-color">...</em>}</code>-s.</p>
+
+ <div class="callout warning">
+ <strong class="callout-label">Warning!</strong>
+
+ <p>A frequent mistake of users is the usage of interpolations
+ in places where it shouldn't/can't be used. Interpolations work
+ <em>only</em> in <a href="dgui_template_overallstructure.html"><span class="marked-text">text</span> sections</a> (e.g.
+ <code class="inline-code"><h1>Hello ${name}!</h1></code>) and in
+ string literals (e.g. <code class="inline-code"><#include
+ "/footer/${company}.html"></code>). A typical bad usage is
+ <code class="inline-code"><#if ${isBig}>Wow!</#if></code>, which
+ is syntactically <em>WRONG</em>. You should simply
+ write <code class="inline-code"><#if isBig>Wow!</#if></code>.
+ Also, <code class="inline-code"><#if "${isBig}">Wow!</#if></code>
+ is <em>WRONG</em> too, since the parameter value
+ will be a string, and the <code class="inline-code">if</code> directive wants
+ a boolean value, so it will cause a runtime error.</p>
+ </div>
+
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_get_character">Getting a character</h3>
+
+
+
+
+
+
+ <p>You can get a single character of a string at a given index
+ similarly as you can <a href="#dgui_template_exp_var_sequence">read the subvariable of a
+ sequence</a>, e.g. <code class="inline-code">user[0]</code>. The result will
+ be a string whose length is 1; FTL doesn't have a separate
+ character type. As with sequence subvariables, the index must be a
+ number that is at least 0 and less than the length of the string,
+ or else an error will abort the template processing.</p>
+
+ <p>Since the sequence subvariable syntax and the character
+ getter syntax clashes, you can use the character getter syntax
+ only if the variable is not a sequence as well (which is possible
+ because FTL supports multi-typed values), since in that case the
+ sequence behavior prevails. (To work this around, you can use
+ <a href="ref_builtins_string.html#ref_builtin_string_for_string">the
+ <code>string</code> built-in</a>, e.g.
+ <code class="inline-code">user?string[0]</code>. Don't worry if you don't
+ understand this yet; built-ins will be discussed later.)</p>
+
+ <p>Example (assume that user is ``Big Joe''):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${user[0]}
+${user[4]}</pre></div>
+
+ <p>will print (note that the index of the first character is
+ 0):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">B
+J</pre></div>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>You can get a range of characters in the same way as you
+ <a href="#dgui_template_exp_seqenceop_slice">get a sequence
+ slice</a>, e.g <code class="inline-code">${user[1..4]}</code> and
+ <code class="inline-code">${user[4..]}</code>. However, it's now depreacted to
+ utilize this, and instead you should use <a href="ref_builtins_string.html#ref_builtin_substring">the <code>substring</code>
+ built-in</a>; built-ins will be discussed later.</p>
+ </div>
+
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_sequenceop">Sequence operations</h2>
+
+
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_sequenceop_cat">Concatenation</h3>
+
+
+
+
+
+
+
+
+
+
+ <p>You can concatenate sequences in the same way as strings,
+ with <code class="inline-code">+</code>. Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#list ["Joe", "Fred"] + ["Julia", "Kate"] as user>
+- ${user}
+</#list></pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">- Joe
+- Fred
+- Julia
+- Kate
+ </pre></div>
+
+ <p>Note that sequence concatenation is not to be used for many
+ repeated concatenations, like for appending items to a sequence
+ inside a loop. It's just for things like <code class="inline-code"><#list users
+ + admins as person></code>. Although concatenating sequences
+ is fast and its speed is independently of the size of the
+ concatenated sequences, the resulting sequence will be always a
+ little bit slower to read than the original two sequences were.
+ This way the result of many repeated concatenations is a sequence
+ that is slow to read.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_seqenceop_slice">Sequence slice</h3>
+
+
+
+
+
+
+
+
+ <p>With
+ <code class="inline-code">[<em class="code-color">firstindex</em>..<em class="code-color">lastindex</em>]</code>
+ you can get a slice of a sequence, where
+ <code class="inline-code"><em class="code-color">firstindex</em></code> and
+ <code class="inline-code"><em class="code-color">lastindex</em></code> are
+ expressions evaluate to number. For example, if
+ <code class="inline-code">seq</code> stores the sequence <code class="inline-code">"a"</code>,
+ <code class="inline-code">"b"</code>, <code class="inline-code">"c"</code>,
+ <code class="inline-code">"d"</code>, <code class="inline-code">"e"</code>,
+ <code class="inline-code">"f"</code> then the expression
+ <code class="inline-code">seq[1..4]</code> will evaluate to a sequence that
+ contains <code class="inline-code">"b"</code>, <code class="inline-code">"c"</code>,
+ <code class="inline-code">"d"</code>, <code class="inline-code">"e"</code> (since the item at
+ index 1 is <code class="inline-code">"b"</code>, and the item at index 4 is
+ <code class="inline-code">"e"</code>).</p>
+
+ <p>The <code class="inline-code"><em class="code-color">lastindex</em></code>
+ can be omitted, in which case it defaults to the index of the last
+ item of the sequence. For example, if <code class="inline-code">seq</code>
+ stores the sequence <code class="inline-code">"a"</code>,
+ <code class="inline-code">"b"</code>, <code class="inline-code">"c"</code>,
+ <code class="inline-code">"d"</code>, <code class="inline-code">"e"</code>,
+ <code class="inline-code">"f"</code> again, then <code class="inline-code">seq[3..]</code>
+ will evaluate to a sequence that contains <code class="inline-code">"d"</code>,
+ <code class="inline-code">"e"</code>, <code class="inline-code">"f"</code>.</p>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p><code class="inline-code"><em class="code-color">lastindex</em></code>
+ can be omitted only since FreeMarker 2.3.3.</p>
+ </div>
+
+
+ <p>An attempt to access a subvariable past the last subvariable
+ or before the first subvariable of the sequence will cause an
+ error and abort the processing of the template.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_hashop">Hash operations</h2>
+
+
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_hashop_cat">Concatenation</h3>
+
+
+
+
+
+
+
+
+
+
+ <p>You can concatenate hashes in the same way as strings, with
+ <code class="inline-code">+</code>. If both hashes contain the same key, the
+ hash on the right-hand side of the <code class="inline-code">+</code> takes
+ precedence. Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign ages = {"Joe":23, "Fred":25} + {"Joe":30, "Julia":18}>
+- Joe is ${ages.Joe}
+- Fred is ${ages.Fred}
+- Julia is ${ages.Julia}</pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">- Joe is 30
+- Fred is 25
+- Julia is 18</pre></div>
+
+ <p>Note that hash concatenation is not to be used for many
+ repeated concatenations, like for adding items to a hash inside a
+ loop. It's the same as with the <a href="#dgui_template_exp_sequenceop_cat">sequence
+ concatenation</a>.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_arit">Arithmetical calculations</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <p>This is the basic 4-function calculator arithmetic plus the
+ modulus operator. So the operators are:</p>
+
+ <ul>
+ <li>
+ Addition: <code class="inline-code">+</code>
+ </li>
+
+ <li>
+ Subtraction: <code class="inline-code">-</code>
+ </li>
+
+ <li>
+ Multiplication: <code class="inline-code">*</code>
+ </li>
+
+ <li>
+ Division: <code class="inline-code">/</code>
+ </li>
+
+ <li>
+ Modulus (remainder): <code class="inline-code">%</code>
+ </li>
+ </ul>
+
+
+
+ <p>Example:</p>
+
+ <p>Assuming that <code class="inline-code">x</code> is 5, it will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">-75
+2.5
+2</pre></div>
+
+ <p>Both operands must be expressions which evaluate to a
+ numerical value. So the example below will cause an error when
+ FreeMarker tries to evaluate it, since <code class="inline-code">"5"</code> is a
+ string and not the number 5:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${3 * "5"} <#-- WRONG! --></pre></div>
+
+ <p>There is an exception to the above rule. The
+ <code class="inline-code">+</code> operator, is used to <a href="#dgui_template_exp_stringop_interpolation">concatenate
+ strings</a> as well. If on one side of <code class="inline-code">+</code> is a
+ string and on the other side of <code class="inline-code">+</code> is a numerical
+ value, then it will convert the numerical value to string (using the
+ format appropriate for language of the page) and then use the
+ <code class="inline-code">+</code> as string concatenation operator.
+ Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${3 + "5"}</pre></div>
+
+ <p>will output this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">35</pre></div>
+
+ <p>Generally, FreeMarker never converts a string to a number
+ automatically, but it may convert a number to a string
+ automatically.</p>
+
+ <p> People often want only the integer part of the result
+ of a division (or of other calculations). This is possible with the
+ <code class="inline-code">int</code> built-in. (Built-ins are explained <a href="#dgui_template_exp_builtin">later</a>):</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${(x/2)?int}
+${1.1?int}
+${1.999?int}
+${-1.1?int}
+${-1.999?int}</pre></div>
+
+ <p>Assuming that <code class="inline-code">x</code> is 5, it will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">2
+1
+1
+-1
+-1</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_comparison">Comparison</h2>
+
+
+
+
+ <p>Sometimes you want to know if two values are equal or not, or
+ which value is the greater.</p>
+
+ <p>To show concrete examples I will use the <code class="inline-code">if</code>
+ directive here. The usage of <code class="inline-code">if</code> directive is:
+ <code class="inline-code"><#if
+ <em class="code-color">expression</em>>...</#if></code>,
+ where expression must evaluate to a boolean value or else an error
+ will abort the processing of the template. If the value of
+ expression is <code class="inline-code">true</code> then the things between the
+ begin and end-tag will be processed, otherwise they will be
+ skipped.</p>
+
+ <p>To test two values for equality you use <code class="inline-code">=</code>
+ (or <code class="inline-code">==</code> as in Java or C; the two are absolutely
+ equivalent.) To test two values for inequality you use
+ <code class="inline-code">!=</code>. For example, assume that
+ <code class="inline-code">user</code> is ``Big Joe'':</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if <strong>user = "Big Joe"</strong>>
+ It is Big Joe
+</#if>
+<#if <strong>user != "Big Joe"</strong>>
+ It is not Big Joe
+</#if></pre></div>
+
+ <p>The <code class="inline-code">user = "Big Joe"</code> expression in the
+ <code class="inline-code"><#if ...></code> will evaluate to the boolean
+ <code class="inline-code">true</code>, so the above will say ``It is Big
+ Joe''.</p>
+
+ <p>The expressions on both sides of the <code class="inline-code">=</code> or
+ <code class="inline-code">!=</code> must evaluate to a scalar. Furthermore, the
+ two scalars must have the same type (i.e. strings can only be
+ compared to strings and numbers can only be compared to numbers,
+ etc.) or else an error will abort template processing. For example
+ <code class="inline-code"><#if 1 = "1"></code> will cause an error. Note
+ that FreeMarker does exact comparison, so string comparisons are
+ case and white-space sensitive: <code class="inline-code">"x"</code> and
+ <code class="inline-code">"x "</code> and <code class="inline-code">"X"</code> are not equal
+ values.</p>
+
+ <p>For numerical and date values you can also use
+ <code class="inline-code"><</code>, <code class="inline-code"><=</code>,
+ <code class="inline-code">>=</code> and <code class="inline-code">></code>. You can't use
+ them for strings! Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if x <strong><=</strong> 12>
+ x is less or equivalent with 12
+</#if></pre></div>
+
+ <p>There is a little problem with <code class="inline-code">>=</code> and
+ <code class="inline-code">></code>. FreeMarker interprets the
+ <code class="inline-code">></code> as the closing character of the FTL tag. To
+ prevent this, you have to put the expression into <a href="#dgui_template_exp_parentheses">parenthesis</a>:
+ <code class="inline-code"><#if (x > y)></code>. Or, you can use
+ <code class="inline-code">&gt;</code> and <code class="inline-code">&lt;</code> on the
+ place of the problematic relation marks: <code class="inline-code"><#if x &gt;
+ y></code>. (Note that in general FTL does not support entity
+ references (those
+ <code class="inline-code">&<em class="code-color">...</em>;</code> things) in
+ FTL tags; it is just an exception with the arithmetical
+ comparisons.). Also, as an alternative you can use
+ <code class="inline-code">lt</code> instead of <code class="inline-code"><</code>,
+ <code class="inline-code">lte</code> instead of <code class="inline-code"><=</code>,
+ <code class="inline-code">gt</code> instead of <code class="inline-code">></code> and
+ <code class="inline-code">gte</code> instead of <code class="inline-code">>=</code>. And, for
+ historical reasons FTL also understands <code class="inline-code">\lt</code>,
+ <code class="inline-code">\lte</code>, <code class="inline-code">\gt</code> and
+ <code class="inline-code">\gte</code> which are the same as the ones without the
+ backslash.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_logicalop">Logical operations</h2>
+
+
+
+
+
+
+
+
+
+
+
+
+ <p>Just the usual logical operators:</p>
+
+ <ul>
+ <li>
+ Logical or: <code class="inline-code">||</code>
+ </li>
+
+ <li>
+ Logical and: <code class="inline-code">&&</code>
+ </li>
+
+ <li>
+ Logical not: <code class="inline-code">!</code>
+ </li>
+ </ul>
+
+ <p>The operators will work with boolean values only. Otherwise an
+ error will abort the template processing.</p>
+
+ <p>Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if x < 12 <strong>&&</strong> color = "green">
+ We have less than 12 things, and they are green.
+</#if>
+<#if <strong>!</strong>hot> <#-- here hot must be a boolean -->
+ It's not hot.
+</#if></pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_builtin">Built-ins</h2>
+
+
+
+
+ <p>Built-ins provide, as the name suggest, certain built-in
+ functionality that is always available. Typically, a built-in
+ provides a different version of a variable, or some information
+ about the variable in question. The syntax for accessing a built-in
+ is like that of accessing a subvariable in a hash, except that you
+ use the question mark instead of a dot. For example, to get the
+ upper case version of a string:
+ <code class="inline-code">user?upper_case</code>.</p>
+
+ <p>You can find the complete <a href="ref_builtins.html">list of
+ built-ins in the Reference</a>. For now, just a few of the more
+ important ones:</p>
+
+ <ul>
+ <li>
+ <p>Built-ins to use with strings:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">html</code>: The string with all special
+ HTML characters replaced with entity references (E.g.
+ <code class="inline-code"><</code> with
+ <code class="inline-code">&lt;</code>)</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">cap_first</code>: The string with the
+ first letter converted to upper case</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">lower_case</code>: The lowercase version
+ of the string</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">upper_case</code>: The uppercase version
+ of the string</p>
+ </li>
+
+ <li>
+ <p><code class="inline-code">trim</code>: The string without leading
+ and trailing <a href="gloss.html#gloss.whiteSpace">white-spaces</a></p>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <p>Built-ins to use with sequences:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">size</code>: The number of elements in the
+ sequence</p>
+ </li>
+ </ul>
+ </li>
+
+ <li>
+ <p>Built-ins to use with numbers:</p>
+
+ <ul>
+ <li>
+ <p><code class="inline-code">int</code>: The integer part of a number
+ (e.g. <code class="inline-code">-1.9?int</code> is
+ <code class="inline-code">-1</code>)</p>
+ </li>
+ </ul>
+ </li>
+ </ul>
+
+ <p>Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${test?html}
+${test?upper_case?html}</pre></div>
+
+ <p>Assuming that <code class="inline-code">test</code> stores the string ``Tom
+ & Jerry'', the output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">Tom &amp; Jerry
+TOM &amp; JERRY</pre></div>
+
+ <p>Note the <code class="inline-code">test?upper_case?html</code>. Since the
+ result of <code class="inline-code">test?upper_case</code> is a string, you can
+ use the <code class="inline-code">html</code> built-in with it.</p>
+
+ <p>Another example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${seasons?size}
+${seasons[1]?cap_first} <#-- left side can by any expression -->
+${"horse"?cap_first}</pre></div>
+
+ <p>Assuming that <code class="inline-code">seasons</code> stores the sequence
+ <code class="inline-code">"winter"</code>, <code class="inline-code">"spring"</code>,
+ <code class="inline-code">"summer"</code>, <code class="inline-code">"autumn"</code>, the output
+ will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">4
+Spring
+Horse</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_methodcall">Method call</h2>
+
+
+
+
+
+
+ <p>If you have a method then you can use the method call
+ operation on it. The method call operation is a comma-separated list
+ of expressions in parentheses. These values are called parameters.
+ The method call operation passes these values to the method which
+ will in turn return a result. This result will be the value of the
+ whole method call expression.</p>
+
+ <p>For example, assume the programmers have made available a
+ method variable called <code class="inline-code">repeat</code>. You give a string
+ as the first parameter, and a number as the second parameter, and it
+ returns a string which repeats the first parameter the number of
+ times specified by the second parameter.</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${repeat("What", 3)}</pre></div>
+
+ <p>will print:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">WhatWhatWhat</pre></div>
+
+ <p>Here <code class="inline-code">repeat</code> was evaluated to the method
+ variable (according to how you <a href="#dgui_template_exp_var_toplevel">access top-level
+ variables</a>) and then <code class="inline-code">("What", 3)</code> invoked
+ that method.</p>
+
+ <p>I would like to emphasize that method calls are just plain
+ expressions, like everything else. So this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${repeat(repeat("x", 2), 3) + repeat("What", 4)?upper_case}</pre></div>
+
+ <p>will print this:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">xxxxxxWHATWHATWHATWHAT</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_missing">Handling missing values</h2>
+
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>These operators exist since FreeMarker 2.3.7 (replacing the
+ <code class="inline-code">default</code>, <code class="inline-code">exists</code> and
+ <code class="inline-code">if_exists</code> built-ins).</p>
+ </div>
+
+
+
+
+
+
+
+
+
+
+
+
+ <p>As we explained earlier, an error will occur and abort the
+ template processing if you try to access a missing variable. However
+ two special operators can suppress this error, and handle the
+ problematic situation. The handled variable can be top-level
+ variable, hash subvariable, or sequence subvariable as well.
+ Furthermore these operators handle the situation when a method call
+ doesn't return a value <span class="marked-for-programmers">(from the
+ viewpoint of Java programmers: it returns <code class="inline-code">null</code> or
+ it's return type is <code class="inline-code">void</code>)</span>, so it's more
+ correct to say that these operators handle missing values in
+ general, rather than just missing variables.</p>
+
+ <p><span class="marked-for-programmers">For those who know what's Java
+ <code class="inline-code">null</code>, FreeMarker 2.3.<em>x</em>
+ treats them as missing values. Simply, the template language doesn't
+ know the concept of <code class="inline-code">null</code>. For example, if you
+ have a bean that has a <code class="inline-code">maidenName</code> property, and
+ the value of that property is <code class="inline-code">null</code>, then that's
+ the same as if there were no such property at all, as far as the
+ template is concerned (assuming you didn't configured FreeMarker to
+ use some extreme object wrapper, that is). The result of a method
+ call that returns <code class="inline-code">null</code> is also treated as a
+ missing variable (again, assuming that you use some usual object
+ wrapper). See more <a href="app_faq.html#faq_null">in the
+ FAQ</a>.</span></p>
+
+ <div class="callout note">
+ <strong class="callout-label">Note:</strong>
+
+ <p>If you wonder why is FreeMarker so picky about missing
+ variables, <a href="app_faq.html#faq_picky_about_missing_vars">read this
+ FAQ entry</a>.</p>
+ </div>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_missing_default">Default value operator</h3>
+
+
+
+
+ <p>Synopsis:
+ <code class="inline-code"><em class="code-color">unsafe_expr</em>!<em class="code-color">default_expr</em></code>
+ or <code class="inline-code"><em class="code-color">unsafe_expr</em>!</code> or
+ <code class="inline-code">(<em class="code-color">unsafe_expr</em>)!<em class="code-color">default_expr</em></code>
+ or
+ <code class="inline-code">(<em class="code-color">unsafe_expr</em>)!</code></p>
+
+ <p>This operator allows you to specify a default value for the
+ case when the value is missing.</p>
+
+ <p>Example. Assume no variable called <code class="inline-code">mouse</code>
+ is present:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${mouse!"No mouse."}
+<#assign mouse="Jerry">
+${mouse!"No mouse."}</pre></div>
+
+ <p>The output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">No mouse.
+Jerry</pre></div>
+
+ <p>The default value can be any kind of expression, so it
+ doesn't have to be a string. For example you can write
+ <code class="inline-code">hits!0</code> or <code class="inline-code">colors!["red", "green",
+ "blue"]</code>. There is no restriction regarding the
+ complexity of the expression that specifies the default value, for
+ example you can write: <code class="inline-code">cargo.weight!(item.weight *
+ itemCount + 10)</code>.</p>
+
+ <div class="callout warning">
+ <strong class="callout-label">Warning!</strong>
+
+ <p>If you have a composite expression after the
+ <code class="inline-code">!</code>, like <code class="inline-code">1 + x</code>,
+ <em>always</em> use parenthesses, like
+ <code class="inline-code">${x!(1 + y)}</code> or <code class="inline-code">${(x!1) +
+ y)}</code>, depending on which interpretation you meant.
+ That's needed because due to a programming mistake in FreeMarker
+ 2.3.x, the precedence of <code class="inline-code">!</code> (when it's used as
+ default value operator) is very low at its right side. This
+ means that, for example, <code class="inline-code">${x!1 + y}</code> is
+ misinterpreted by FreeMarker as <code class="inline-code">${x!(1 + y)}</code>
+ while it should mean <code class="inline-code">${(x!1) + y}</code>. This
+ programming error will be fixed in FreeMarker 2.4, so you should
+ not utilize this wrong behavior, or else your templates will
+ break with FreeMarker 2.4!</p>
+ </div>
+
+
+ <p>If the default value is omitted, then it will be empty
+ string and empty sequence and empty hash at the same time. (This
+ is possible because FreeMarker allows multi-type values.) Note the
+ consequence that you can't omit the default value if you want it
+ to be <code class="inline-code">0</code> or <code class="inline-code">false</code>.
+ Example:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">(${mouse!})
+<#assign mouse = "Jerry">
+(${mouse!})</pre></div>
+
+ <p>The output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">()
+(Jerry)</pre></div>
+
+ <div class="callout warning">
+ <strong class="callout-label">Warning!</strong>
+
+ <p>Due to syntactical ambiguities <code class="inline-code"><@something
+ a=x! b=y /></code> will be interpreted as
+ <code class="inline-code"><@something a=x!(b=y) /></code>, that is, the
+ <code class="inline-code">b=y</code> will be interpreted as a comparison that
+ gives the default value for <code class="inline-code">x</code>, rather than
+ the specification of the <code class="inline-code">b</code> parameter. To
+ prevent this, write: <code class="inline-code"><@something a=(x!) b=y
+ /></code></p>
+ </div>
+
+
+ <p>You can use this operator in two ways with non-top-level
+ variables:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">product.color!"red"</pre></div>
+
+ <p>This will handle if <code class="inline-code">color</code> is missing
+ inside <code class="inline-code">product</code> (and returns
+ <code class="inline-code">"red"</code> if so), but will not handle if
+ <code class="inline-code">product</code> is missing. That is, the
+ <code class="inline-code">product</code> variable itself must exist, otherwise
+ the template processing will die with error.</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">(product.color)!"red"</pre></div>
+
+ <p>This will handle if <code class="inline-code">product.color</code> is
+ missing. That is, if <code class="inline-code">product</code> is missing, or
+ <code class="inline-code">product</code> exists but it does not contain
+ <code class="inline-code">color</code>, the result will be
+ <code class="inline-code">"red"</code>, and no error will occur. The important
+ difference between this and the previous example is that when
+ surrounded with parentheses, it is allowed for any component of
+ the expression to be undefined, while without parentheses only the
+ last component of the expression is allowed to be
+ undefined.</p>
+
+ <p>Of course, the default value operator can be used with
+ sequence subvariables as well:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#assign seq = ['a', 'b']>
+${seq[0]!'-'}
+${seq[1]!'-'}
+${seq[2]!'-'}
+${seq[3]!'-'}</pre></div>
+
+ <p>the outpur will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output">a
+b
+-
+-</pre></div>
+
+ <p>A negative sequence index (as
+ <code class="inline-code">seq[-1]!'-'</code>) will always cause an error, you
+ can't suppress that with this or any other operator.</p>
+
+
+
+
+
+
+
+<h3 class="content-header header-section3" id="dgui_template_exp_missing_test">Missing value test operator</h3>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ <p>Synopsis:
+ <code class="inline-code"><em class="code-color">unsafe_expr</em>??</code> or
+ <code class="inline-code">(<em class="code-color">unsafe_expr</em>)??</code></p>
+
+ <p>This operator tells if a value is missing or not. Depending
+ on that, the result is either <code class="inline-code">true</code> or
+ <code class="inline-code">false</code>.</p>
+
+ <p>Example. Assume no variable called <code class="inline-code">mouse</code>
+ is present:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"><#if mouse??>
+ Mouse found
+<#else>
+ No mouse found
+</#if>
+Creating mouse...
+<#assign mouse = "Jerry">
+<#if mouse??>
+ Mouse found
+<#else>
+ No mouse found
+</#if></pre></div>
+
+ <p>The output will be:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-output"> No mouse found
+Creating mouse...
+ Mouse found</pre></div>
+
+ <p>With non-top-level variables the rules are the same as with
+ the default value operator, that is, you can write
+ <code class="inline-code">product.color??</code> and
+ <code class="inline-code">(product.color)??</code>.</p>
+
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_parentheses">Parentheses</h2>
+
+
+
+
+ <p>Parentheses can be used to group any expressions. Some
+ examples:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template"> <#-- Output will be: -->
+${3 * 2 + 2} <#-- 8 -->
+${3 * (2 + 2)} <#-- 12 -->
+${3 * ((2 + 2) * (1 / 2))} <#-- 6 -->
+${"green " + "mouse"?upper_case} <#-- green MOUSE -->
+${("green " + "mouse")?upper_case} <#-- GREEN MOUSE -->
+<#if !( color = "red" || color = "green")>
+ The color is nor red nor green
+</#if></pre></div>
+
+ <p>Note that the parentheses of a <a href="#dgui_template_exp_methodcall">method call
+ expressions</a> have nothing to do with the parentheses used for
+ grouping.</p>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_whitespace">White-space in expressions</h2>
+
+
+ <p>FTL ignores superfluous <a href="gloss.html#gloss.whiteSpace">white-space</a> in expressions. So
+ these are totally equivalent:</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${x + ":" + book.title?upper_case}</pre></div>
+
+ <p>and</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${x+":"+book.title?upper_case}</pre></div>
+
+ <p>and</p>
+
+
+
+<div class="code-wrapper"><pre class="code-block code-template">${
+ x
+ + ":" + book . title
+ ? upper_case
+ }</pre></div>
+
+
+
+
+
+<h2 class="content-header header-section2" id="dgui_template_exp_precedence">Operator precedence</h2>
+
+
+
+
+
+
+ <p>The following table shows the precedence assigned to the
+ operators. The operators in this table are listed in precedence
+ order: the higher in the table an operator appears, the higher its
+ precedence. Operators with higher precedence are evaluated before
+ operators with a relatively lower precedence. Operators on the same
+ line have equal precedence. When binary operators (operators with
+ two ``parameters'', as <code class="inline-code">+</code> and
+ <code class="inline-code">-</code>) of equal precedence appear next to each other,
+ they are evaluated in left-to-right order.</p>
+
+ <div class="table-responsive">
+ <table class="table">
+
+ <thead>
+ <tr>
+ <th>Operator group</th>
+
+
+ <th>Operators</th>
+
+ </tr>
+
+ </thead>
+
+
+ <tbody>
+ <tr>
+ <td>highest precedence operators</td>
+
+
+ <td><code class="inline-code">[<em class="code-color">subvarName</em>]
+ [<em class="code-color">subStringRange</em>] . ?
+ (<em class="code-color">methodParams</em>)
+ <em class="code-color">expr</em>!
+ <em class="code-color">expr</em>??</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td>unary prefix operators</td>
+
+
+ <td><code class="inline-code">+<em class="code-color">expr</em>
+ -<em class="code-color">expr</em> !expr</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td>multiplicative</td>
+
+
+ <td><code class="inline-code">* / %</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td>additive</td>
+
+
+ <td><code class="inline-code">+ -</code></td>
+
+ </tr>
+
+
+ <tr>
+ <td>relational</td>
+
+
+ <td><code class="inline-code">< > <= >=</code> (and quivalents:
+ <code class="inline-code">gt</code>, <code class="inline-code">lt</code>, etc.)</td>
+
+ </tr>
+
+
+ <tr>
+ <td>equality</td>
+
+
+ <td><code class="inline-code">== !=</code> (and equivalents:
+ <code class="inline-code">=</code>)</td>
+
+ </tr>
+
+
+ <tr>
+ <td>logical AND</td>
+
+
+ <td><code class="inline-code">&&</code></td>
... 113201 lines suppressed ...