Update: Translations from eints
[openttd-github.git] / src / script / api / script_text.hpp
blob5cc3a52fe3ec048ea9bf4cda74876c7561e43fc4
1 /*
2 * This file is part of OpenTTD.
3 * OpenTTD 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 2.
4 * OpenTTD 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.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6 */
8 /** @file script_text.hpp Everything to handle text which can be translated. */
10 #ifndef SCRIPT_TEXT_HPP
11 #define SCRIPT_TEXT_HPP
13 #include "script_object.hpp"
14 #include "../../core/alloc_type.hpp"
16 #include <variant>
18 /**
19 * Internal parent object of all Text-like objects.
20 * @api -all
22 class Text : public ScriptObject {
23 public:
24 /**
25 * Convert a ScriptText to a normal string.
26 * @return A string.
27 * @api -all
29 virtual std::string GetEncodedText() = 0;
31 /**
32 * Convert a #ScriptText into a decoded normal string.
33 * @return A string.
34 * @api -all
36 const std::string GetDecodedText();
39 /**
40 * Internally used class to create a raw text in a Text object.
41 * @api -all
43 class RawText : public Text {
44 public:
45 RawText(const std::string &text);
47 std::string GetEncodedText() override { return this->text; }
48 private:
49 const std::string text;
52 /**
53 * Class that handles all text related functions. You can define a language
54 * file in lang/english.txt, in the same format as OpenTTD does, including
55 * tags like {BLACK}, {STRING1} etc. The name given to this string is made
56 * available to you in ScriptText, for example: ScriptText.STR_NEWS, if your
57 * english.txt contains: STR_NEWS :{BLACK}Welcome {COMPANY}!
59 * In translation files like lang/dutch.txt you can then translate such
60 * strings, like: STR_NEWS :{BLACK}Hallo {COMPANY}!
61 * When the user has the dutch language selected, it will automatically use
62 * the translated string when available. The fallback language is always
63 * the english language.
65 * If you use parameters in your strings, you will have to define those
66 * parameters, for example like this:
67 * \code local text = ScriptText(ScriptText.STR_NEWS);
68 * text.AddParam(1); \endcode
69 * This will set the {COMPANY} to the name of Company 1. Alternatively you
70 * can directly give those arguments to the ScriptText constructor, like this:
71 * \code local text = ScriptText(ScriptText.STR_NEWS, 1); \endcode
73 * @api game
75 class ScriptText : public Text , public ZeroedMemoryAllocator {
76 public:
77 static const int SCRIPT_TEXT_MAX_PARAMETERS = 20; ///< The maximum amount of parameters you can give to one object.
79 #ifndef DOXYGEN_API
80 /**
81 * The constructor wrapper from Squirrel.
83 ScriptText(HSQUIRRELVM vm);
84 #else
85 /**
86 * Generate a text from string. You can set parameters to the instance which
87 * can be required for the string.
88 * @param string The string of the text.
89 * @param ... Optional arguments for this string.
91 ScriptText(StringID string, ...);
92 #endif /* DOXYGEN_API */
94 #ifndef DOXYGEN_API
95 /**
96 * Used for .param_N and [] set from Squirrel.
98 SQInteger _set(HSQUIRRELVM vm);
101 * Set the parameter.
103 SQInteger SetParam(HSQUIRRELVM vm);
106 * Add an parameter
108 SQInteger AddParam(HSQUIRRELVM vm);
109 #else
111 * Set the parameter to a value.
112 * @param parameter Which parameter to set.
113 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
115 void SetParam(int parameter, object value);
118 * Add a value as parameter (appending it).
119 * @param value The value of the parameter. Has to be string, integer or an instance of the class ScriptText.
120 * @return The same object as on which this is called, so you can chain.
122 ScriptText *AddParam(object value);
123 #endif /* DOXYGEN_API */
126 * @api -all
128 std::string GetEncodedText() override;
130 private:
131 using ScriptTextRef = ScriptObjectRef<ScriptText>;
132 using ScriptTextList = std::vector<ScriptText *>;
133 using Param = std::variant<SQInteger, std::string, ScriptTextRef>;
135 struct ParamCheck {
136 StringID owner;
137 int idx;
138 Param *param;
139 bool used;
140 const char *cmd;
142 ParamCheck(StringID owner, int idx, Param *param) : owner(owner), idx(idx), param(param), used(false), cmd(nullptr) {}
144 void Encode(std::back_insert_iterator<std::string> &output, const char *cmd);
147 using ParamList = std::vector<ParamCheck>;
148 using ParamSpan = std::span<ParamCheck>;
150 StringID string;
151 Param param[SCRIPT_TEXT_MAX_PARAMETERS];
152 int paramc;
155 * Internal function to recursively fill a list of parameters.
156 * The parameters are added as _GetEncodedText used to encode them
157 * before the addition of parameter validation.
158 * @param params The list of parameters to fill.
159 * @param seen_texts The list of seen ScriptText.
161 void _FillParamList(ParamList &params, ScriptTextList &seen_texts);
164 * Internal function for recursive calling this function over multiple
165 * instances, while writing in the same buffer.
166 * @param output The output to write the encoded text to.
167 * @param param_count The number of parameters that are consumed by the string.
168 * @param args The parameters to be consumed.
169 * @param first Whether it's the first call in the recursion.
171 void _GetEncodedText(std::back_insert_iterator<std::string> &output, int &param_count, ParamSpan args, bool first);
174 * Set a parameter, where the value is the first item on the stack.
176 SQInteger _SetParam(int k, HSQUIRRELVM vm);
179 #endif /* SCRIPT_TEXT_HPP */