The Battle for Wesnoth  1.19.10+dev
markup.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2024 - 2025
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include "color.hpp"
18 #include "exceptions.hpp"
19 // This file isn't needed by any of these functions, but this allows any
20 // standard color to be passed to span_color without an extra include.
21 #include "font/standard_colors.hpp"
22 #include "formatter.hpp"
23 
24 #include <string>
25 #include <string_view>
26 #include <vector>
27 
28 class config;
29 
30 namespace markup
31 {
32 /**
33  * A Help markup tag corresponding to a linebreak.
34  * @see gui2::rich_label for details on how this tag is parsed.
35  */
36 constexpr std::string_view br{"<br/>"};
37 
38 /**
39  * Wraps the given data in the specified tag.
40  *
41  * @param tag The tag ("b", "i", etc).
42  * @param data The content to wrap with @a tag.
43  * Each argument must be writable to a stringstream.
44  *
45  * @note Special formatting characters in the input are not escaped.
46  * If such behavior is needed, it must be handled by the caller.
47  * If the concatenation of @a data results in an empty string,
48  * an empty string is returned in lieu of formatting tags.
49  */
50 template<typename... Args>
51 std::string tag(std::string_view tag, Args&&... data)
52 {
53  std::string input = (formatter() << ... << data);
54  if(input.empty()) return {};
55  return formatter() << "<" << tag << ">" << input << "</" << tag << ">";
56 }
57 
58 /** @todo is it safe to use a string_view for both key and value */
59 using tag_attributes = std::vector<std::pair<std::string_view, std::string_view>>;
60 
61 /**
62  * Wraps the given data in the specified tag.
63  *
64  * @param tag The tag ("b", "i", etc).
65  * @param attrs A vector containing the attribute key-value pairs.
66  * @param data The content to wrap with @a tag.
67  * Each argument must be writable to a stringstream.
68  *
69  * @note Special formatting characters in the input are not escaped.
70  * If such behavior is needed, it must be handled by the caller.
71  * If the concatenation of @a data results in an empty string,
72  * an empty string is returned in lieu of formatting tags.
73  */
74 template<typename... Args>
75 std::string tag(std::string_view tag, const tag_attributes& attrs, Args&&... data)
76 {
77  std::string input = (formatter() << ... << data);
78  if(input.empty()) return {};
79  std::stringstream ss;
80  ss << "<" << tag << " ";
81  for (const auto& [key, value] : attrs) {
82  ss << key << "='" << value << "' ";
83  }
84  ss << ">" << input << "</" << tag << ">";
85  return ss.str();
86 }
87 
88 /**
89  * Wraps the given data in a @c span tag with the specified attribute and value.
90  *
91  * @param key The span attribute ("color", "size", etc).
92  * @param value The attribute value.
93  * @param data The content to format.
94  *
95  * @note See @ref tag for more information.
96  */
97 template<typename Value, typename... Args>
98 std::string span_attribute(std::string_view key, const Value& value, Args&&... data)
99 {
100  return tag("span", {{ key, value }}, std::forward<Args>(data)...);
101 }
102 
103 /**
104  * Applies Pango markup to the input specifying its display color.
105  *
106  * @param color The color_t object from which to retrieve the color.
107  * @param data Variable list of content to enclose inside the span tag.
108  * Each argument must be writable to a stringstream.
109  *
110  * @returns @code `<span color='#color'>#data</span>` @endcode
111  *
112  * @note Special formatting characters in the input are not escaped.
113  * If such behavior is needed, it must be handled by the caller.
114  */
115 template<typename... Args>
116 std::string span_color(const color_t& color, Args&&... data)
117 {
118  return span_attribute("color", color.to_hex_string(), std::forward<Args>(data)...);
119 }
120 
121 /**
122  * Applies Pango markup to the input specifying its display color.
123  *
124  * @param color The hex color string.
125  * @param data Variable list of content to enclose inside the span tag.
126  * Each argument must be writable to a stringstream.
127  *
128  * @returns @code `<span color='#color'>#data</span>` @endcode
129  *
130  * @note Special formatting characters in the input are not escaped.
131  * If such behavior is needed, it must be handled by the caller.
132  */
133 template<typename... Args>
134 std::string span_color(std::string_view color, Args&&... data)
135 {
136  return span_attribute("color", color, std::forward<Args>(data)...);
137 }
138 
139 /**
140  * Applies Pango markup to the input specifying its display size.
141  *
142  * @param size A Pango string size specifier (large, small, x-large, etc).
143  * @param data Variable list of content to concatenate inside the span tag.
144  * Each argument must be writable to a stringstream.
145  *
146  * @returns @code `<span size='#size'>#data</span>` @endcode
147  *
148  * @note Special formatting characters in the input are not escaped.
149  * If such behavior is needed, it must be handled by the caller.
150  */
151 template<typename... Args>
152 std::string span_size(std::string_view size, Args&&... data)
153 {
154  return span_attribute("size", size, std::forward<Args>(data)...);
155 }
156 
157 /**
158  * Applies bold Pango markup to the input.
159  *
160  * @param data Variable list of content to concatenate inside the bold tag.
161  * Each argument must be writable to a stringstream.
162  *
163  * @note Special formatting characters in the input are not escaped.
164  * If such behavior is needed, it must be handled by the caller.
165  */
166 template<typename... Args>
167 std::string bold(Args&&... data)
168 {
169  return tag("b", std::forward<Args>(data)...);
170 }
171 
172 /**
173  * Applies italic Pango markup to the input.
174  *
175  * @param data Variable list of content to enclose inside the italic tag.
176  * Each argument must be writable to a stringstream.
177  *
178  * @note Special formatting characters in the input are not escaped.
179  * If such behavior is needed, it must be handled by the caller.
180  */
181 template<typename... Args>
182 std::string italic(Args&&... data)
183 {
184  return tag("i", std::forward<Args>(data)...);
185 }
186 
187 /**
188  * Generates a Help markup tag corresponding to an image.
189  *
190  * @param src The WML path to the image (i.e., 'units/drakes/arbiter.png')
191  * @param align Alignment of the image. Possible values: left, right, center.
192  * @param floating Is the image a floating image or an inline image?
193  *
194  * @note Special formatting characters in the input are not escaped.
195  * If such behavior is needed, it must be handled by the caller.
196  * @see gui2::rich_label for details on how this tag is parsed.
197  */
198 std::string img(const std::string& src, const std::string& align = "left", bool floating = false);
199 
200 /**
201  * Generates a Help markup tag corresponding to a reference or link.
202  *
203  * @param text User visible text/caption of the link.
204  * @param dst Destination of the link. Can be any string depending on the link handler
205  * in the parsing @ref gui2::rich_label.
206  *
207  * @note Special formatting characters in the input are not escaped.
208  * If such behavior is needed, it must be handled by the caller.
209  * @see gui2::rich_label for details on how this tag is parsed.
210  */
211 std::string make_link(const std::string& text, const std::string& dst);
212 
213 //
214 // Markup Parser
215 //
216 
217 /** Thrown when the help system fails to parse something. */
218 struct parse_error : public game::error
219 {
220  parse_error(const std::string& msg) : game::error(msg) {}
221 };
222 
223 /**
224  * Parse a xml style marked up text string. Return a config with the different parts of the
225  * text. Each markup item is a separate part while the text between
226  * markups are separate parts.
227  */
228 config parse_text(const std::string &text);
229 
230 } // namespace markup
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:158
std::ostringstream wrapper.
Definition: formatter.hpp:40
std::vector< std::pair< std::string_view, std::string_view > > tag_attributes
Definition: markup.hpp:59
std::string italic(Args &&... data)
Applies italic Pango markup to the input.
Definition: markup.hpp:182
std::string span_attribute(std::string_view key, const Value &value, Args &&... data)
Wraps the given data in a span tag with the specified attribute and value.
Definition: markup.hpp:98
std::string img(const std::string &src, const std::string &align, bool floating)
Generates a Help markup tag corresponding to an image.
Definition: markup.cpp:31
std::string make_link(const std::string &text, const std::string &dst)
Generates a Help markup tag corresponding to a reference or link.
Definition: markup.cpp:25
std::string bold(Args &&... data)
Applies bold Pango markup to the input.
Definition: markup.hpp:167
std::string span_color(const color_t &color, Args &&... data)
Applies Pango markup to the input specifying its display color.
Definition: markup.hpp:116
constexpr std::string_view br
A Help markup tag corresponding to a linebreak.
Definition: markup.hpp:36
std::string tag(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
Definition: markup.hpp:51
config parse_text(const std::string &text)
Parse a xml style marked up text string.
Definition: markup.cpp:403
std::string span_size(std::string_view size, Args &&... data)
Applies Pango markup to the input specifying its display size.
Definition: markup.hpp:152
std::size_t size(std::string_view str)
Length in characters of a UTF-8 string.
Definition: unicode.cpp:85
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:109
std::string_view data
Definition: picture.cpp:178
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
The basic class for representing 8-bit RGB or RGBA colour values.
Definition: color.hpp:59
std::string to_hex_string() const
Returns the stored color in rrggbb hex format.
Definition: color.cpp:88
Base class for all the errors encountered by the engine.
Definition: exceptions.hpp:29
Thrown when the help system fails to parse something.
Definition: markup.hpp:219
parse_error(const std::string &msg)
Definition: markup.hpp:220