The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
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.
22#include "formatter.hpp"
23
24#include <string>
25#include <string_view>
26#include <vector>
27
28class config;
29
30namespace markup
31{
32/**
33 * Wraps the given data in the specified tag.
34 *
35 * @param tag The tag ("b", "i", etc).
36 * @param data The content to wrap with @a tag.
37 * Each argument must be writable to a stringstream.
38 *
39 * @note Special formatting characters in the input are not escaped.
40 * If such behavior is needed, it must be handled by the caller.
41 * If the concatenation of @a data results in an empty string,
42 * an empty string is returned in lieu of formatting tags.
43 */
44template<typename... Args>
45std::string tag(std::string_view tag, Args&&... data)
46{
47 std::string input = (formatter() << ... << data);
48 if(input.empty()) return {};
49 return formatter() << "<" << tag << ">" << input << "</" << tag << ">";
50}
51
52/** @todo is it safe to use a string_view for both key and value */
53using tag_attributes = std::vector<std::pair<std::string_view, std::string_view>>;
54
55/**
56 * Wraps the given data in the specified tag.
57 *
58 * @param tag The tag ("b", "i", etc).
59 * @param attrs A vector containing the attribute key-value pairs.
60 * @param data The content to wrap with @a tag.
61 * Each argument must be writable to a stringstream.
62 *
63 * @note Special formatting characters in the input are not escaped.
64 * If such behavior is needed, it must be handled by the caller.
65 * If the concatenation of @a data results in an empty string,
66 * an empty string is returned in lieu of formatting tags.
67 */
68template<typename... Args>
69std::string tag_attr(std::string_view tag, const tag_attributes& attrs, Args&&... data)
70{
71 std::string input = (formatter() << ... << data);
72 if(input.empty()) return {};
73 std::stringstream ss;
74 ss << "<" << tag << (attrs.empty() ? "" : " ");
75 for (const auto& [key, value] : attrs) {
76 ss << key << "='" << value << "' ";
77 }
78 ss << ">" << input << "</" << tag << ">";
79 return ss.str();
80}
81
82/**
83 * Wraps the given data in a @c span tag with the specified attribute and value.
84 *
85 * @param key The span attribute ("color", "size", etc).
86 * @param value The attribute value.
87 * @param data The content to format.
88 *
89 * @note See @ref tag for more information.
90 */
91template<typename Value, typename... Args>
92std::string span_attribute(std::string_view key, const Value& value, Args&&... data)
93{
94 return tag_attr("span", {{ key, value }}, std::forward<Args>(data)...);
95}
96
97/**
98 * Applies Pango markup to the input specifying its display color.
99 *
100 * @param color The color_t object from which to retrieve the color.
101 * @param data Variable list of content to enclose inside the span tag.
102 * Each argument must be writable to a stringstream.
103 *
104 * @returns @code `<span color='#color'>#data</span>` @endcode
105 *
106 * @note Special formatting characters in the input are not escaped.
107 * If such behavior is needed, it must be handled by the caller.
108 */
109template<typename... Args>
110std::string span_color(const color_t& color, Args&&... data)
111{
112 return span_attribute("color", color.to_hex_string(), std::forward<Args>(data)...);
113}
114
115/**
116 * Applies Pango markup to the input specifying its display color.
117 *
118 * @param color The hex color string.
119 * @param data Variable list of content to enclose inside the span tag.
120 * Each argument must be writable to a stringstream.
121 *
122 * @returns @code `<span color='#color'>#data</span>` @endcode
123 *
124 * @note Special formatting characters in the input are not escaped.
125 * If such behavior is needed, it must be handled by the caller.
126 */
127template<typename... Args>
128std::string span_color(std::string_view color, Args&&... data)
129{
130 return span_attribute("color", color, std::forward<Args>(data)...);
131}
132
133/**
134 * Applies Pango markup to the input specifying its display size.
135 *
136 * @param size A Pango string size specifier (large, small, x-large, etc).
137 * @param data Variable list of content to concatenate inside the span tag.
138 * Each argument must be writable to a stringstream.
139 *
140 * @returns @code `<span size='#size'>#data</span>` @endcode
141 *
142 * @note Special formatting characters in the input are not escaped.
143 * If such behavior is needed, it must be handled by the caller.
144 */
145template<typename... Args>
146std::string span_size(std::string_view size, Args&&... data)
147{
148 return span_attribute("size", size, std::forward<Args>(data)...);
149}
150
151/**
152 * Applies bold Pango markup to the input.
153 *
154 * @param data Variable list of content to concatenate inside the bold tag.
155 * Each argument must be writable to a stringstream.
156 *
157 * @note Special formatting characters in the input are not escaped.
158 * If such behavior is needed, it must be handled by the caller.
159 */
160template<typename... Args>
161std::string bold(Args&&... data)
162{
163 return tag("b", std::forward<Args>(data)...);
164}
165
166/**
167 * Applies italic Pango markup to the input.
168 *
169 * @param data Variable list of content to enclose inside the italic tag.
170 * Each argument must be writable to a stringstream.
171 *
172 * @note Special formatting characters in the input are not escaped.
173 * If such behavior is needed, it must be handled by the caller.
174 */
175template<typename... Args>
176std::string italic(Args&&... data)
177{
178 return tag("i", std::forward<Args>(data)...);
179}
180
181/**
182 * Generates a Help markup tag corresponding to an image.
183 *
184 * @param src The WML path to the image (i.e., 'units/drakes/arbiter.png')
185 * @param align Alignment of the image. Possible values: left, right, center.
186 * @param floating Is the image a floating image or an inline image?
187 *
188 * @note Special formatting characters in the input are not escaped.
189 * If such behavior is needed, it must be handled by the caller.
190 * @see gui2::rich_label for details on how this tag is parsed.
191 */
192std::string img(const std::string& src, const std::string& align = "left", bool floating = false);
193
194/**
195 * Generates a Help markup tag corresponding to a reference or link.
196 *
197 * @param text User visible text/caption of the link.
198 * @param dst Destination of the link. Can be any string depending on the link handler
199 * in the parsing @ref gui2::rich_label.
200 *
201 * @note Special formatting characters in the input are not escaped.
202 * If such behavior is needed, it must be handled by the caller.
203 * @see gui2::rich_label for details on how this tag is parsed.
204 */
205std::string make_link(const std::string& text, const std::string& dst);
206
207//
208// Markup Parser
209//
210
211/** Thrown when the help system fails to parse something. */
213{
214 parse_error(const std::string::const_iterator& error_loc, const std::string& error_msg)
215 : game::error(error_msg)
216 , error_position_(error_loc)
217 { }
218
219public:
220 std::string::const_iterator error_location() { return error_position_; }
221
222private:
223 std::string::const_iterator error_position_;
224};
225
226/**
227 * Parse a xml style marked up text string. Return a config with the different parts of the
228 * text. Each markup item is a separate part while the text between
229 * markups are separate parts.
230 */
231config parse_text(const std::string& text);
232
233std::string help_to_pango_markup(const std::string& help_markup);
234
235} // namespace markup
A config object defines a single node in a WML file, with access to child nodes.
Definition config.hpp:157
std::ostringstream wrapper.
Definition formatter.hpp:40
std::vector< std::pair< std::string_view, std::string_view > > tag_attributes
Definition markup.hpp:53
std::string italic(Args &&... data)
Applies italic Pango markup to the input.
Definition markup.hpp:176
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:92
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:37
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:31
std::string bold(Args &&... data)
Applies bold Pango markup to the input.
Definition markup.hpp:161
std::string span_color(const color_t &color, Args &&... data)
Applies Pango markup to the input specifying its display color.
Definition markup.hpp:110
std::string tag_attr(std::string_view tag, const tag_attributes &attrs, Args &&... data)
Wraps the given data in the specified tag.
Definition markup.hpp:69
std::string tag(std::string_view tag, Args &&... data)
Wraps the given data in the specified tag.
Definition markup.hpp:45
std::string help_to_pango_markup(const std::string &help_markup)
Definition markup.cpp:525
config parse_text(const std::string &text)
Parse a xml style marked up text string.
Definition markup.cpp:444
std::string span_size(std::string_view size, Args &&... data)
Applies Pango markup to the input specifying its display size.
Definition markup.hpp:146
std::string_view data
Definition picture.cpp:188
std::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139
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:51
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.
Thrown when the help system fails to parse something.
Definition markup.hpp:213
std::string::const_iterator error_position_
Definition markup.hpp:223
std::string::const_iterator error_location()
Definition markup.hpp:220
parse_error(const std::string::const_iterator &error_loc, const std::string &error_msg)
Definition markup.hpp:214