/** * Class that allows to work with simple text templates in the form of * "Template example, following can be replaced: %1, %2, %3 or %4" or * "%%instigator%% {%%rage_color%% raged} %%target_zed%%!". * Part noted by '%' characters can be replaced with arbitrary values. * It should be more efficient that simply repeatedly calling * `MutableText.Replace()` method. * Copyright 2022 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * * Acedia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * (at your option) any later version. * * Acedia is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ class TextTemplate extends AcediaObject; /** * # `TextTemplate` * * This class allows to do more efficient replacements in the templates of * form "Template example, following can be replaced: %1, %2, %3 or %4" or * "%%instigator%% {%%rage_color%% raged} %%target_zed%%!" that simple * repeating of `MutableText.Replace()` method would allow. * * ## Usage * * All `TextTemplate`s must be initialized before they can be used. * `_.text.MakeTemplate()` method is considered a recommended way to create * a new `TextTemplate` and will initialize it for you. In case you have * manually allocated `TextTemplate` you need to simply call * `TextTemplate.Initialize()` method and provide is with a template source * with designated replaceable part (called *labels*). Any label is designated * by either: * * * Specifying a number after a single '%' character (numeric labels); * * Or specifying a textual value in between double percent sequence "%%". * * Numeric labels can then be replaced with user values by various provided * `Arg...()` methods and text labels by `TextArg...()` methods. To reuse * template with another values replacing specified labels, simply call * `TextTemplate.Reset()` method and fill labels anew. * * ### Escaped sequences * * `TextTemplate` allows for the escaped sequences in the style of * formatted strings: the ones based on the '&' character. More precisely, if * you wish to enter actual '%' character in the template, you can escape it * with "&%" and it will be treaded as simply '%' character and not a part of * label definition. * NOTE: any other escaped sequences will be ignored and translated * one-to-one. For example, "{%%color%% &{...&}&%!}", if specified that * "color" -> "$red", will be translated into "{$red &{...&}%!}". This allows * to use `TextTemplate`s to prepare formatted strings in a more convenient * fashion. * * ### Error handling * * `TextTemplate` lack any means of reporting errors in template's formatting * and tries to correct as many errors as possible. * * 1. If after the single '%' character follows not a number, but another * character - that '%' will be ignored and thrown away; * 2. After opening text label with double percent "%%" to stop specifying * the text label it is sufficient to type a single '%' character. * * ### Numeric labels values * * You can specify any values for numeric labels and they will be filled in * order. However the proper notation is to start with `1` and then use * following natural numbers in order (e.g. "%1", "%2", "%3", etc.). * * ### Text labels duplicates * * It is allowed for the same text label to appear several times in a template * and each entry will be replaced with a specified user value. * * ### Unspecified arguments * * If no argument was given for some label - it will simply be replaced with * empty text. */ // *Labels* will be an internal name for the parts of the template that is // supposed to be replaced. This struct describes one such part. struct Label { // If Label starts with two percent characters ("%%"), then it is // a text Label and we will remember contents within "%%...%%" in this // field (`textLabel != none`). // Otherwise it is a numeric Label and `textLabel` will be set // to `none`. var MutableText textLabel; // For numeric labels - number after that percent character '%'. // In case numeric labels were specified incorrectly, these values will // be normalized to start from `1` and increase by +1, while preserving // their order. var int numberLabel; // Before which part (from `parts`) to insert this Label? var int insertionIndex; }; var private bool initialized; // Remembers amount of numeric labels in the template var private int numericLabelsAmount; // Arrays of labels and parts in between that template got broken into // during initialization var private array