25 std::string
make_link(
const std::string& text,
const std::string&
dst)
28 return formatter() <<
"<ref dst='" <<
dst <<
"'>" << text <<
"</ref>";
31 std::string
img(
const std::string&
src,
const std::string& align,
bool floating)
34 <<
"<img src='" <<
src <<
"' "
35 <<
"float='" << std::boolalpha << floating <<
"' "
36 <<
"align='" << align <<
"' "
96 enum { UNKNOWN, NAMED, HEX, DECIMAL }
type = UNKNOWN;
99 for(; beg != end && *beg !=
';'; ++beg) {
104 }
else if(isalnum(*beg) || *beg ==
'_') {
120 }
else if(isdigit(*beg)) {
136 std::string name =
s.str();
137 entity[
"name"] = name;
139 entity[
"code_point"] =
'<';
140 }
else if(name ==
"gt") {
141 entity[
"code_point"] =
'>';
142 }
else if(name ==
"apos") {
143 entity[
"code_point"] =
'\'';
144 }
else if(name ==
"quot") {
145 entity[
"code_point"] =
'"';
146 }
else if(name ==
"amp") {
147 entity[
"code_point"] =
'&';
156 entity[
"code_point"] =
n;
161 static char parse_escape(std::string::const_iterator& beg, std::string::const_iterator end)
163 assert(*beg ==
'\\');
166 if((beg + 1) != end) {
177 std::ostringstream
s;
178 bool saw_newline =
false;
180 for(; beg != end && *beg != close; ++beg) {
186 if(entity.has_attribute(
"code_point")) {
187 s << unicode_cast<std::string>(entity[
"code_point"].to_int());
191 res.
add_child(
"character_entity", entity);
194 }
else if(*beg ==
'\\') {
196 }
else if(*beg ==
'\n') {
217 assert(beg == end || *beg == close);
221 static std::string
parse_name(std::string::const_iterator& beg, std::string::const_iterator end)
223 std::ostringstream
s;
224 for(; beg != end && (isalnum(*beg) || *beg ==
'_'); ++beg) {
230 static std::pair<std::string, std::string>
parse_attribute(std::string::const_iterator& beg, std::string::const_iterator end,
bool allow_empty)
232 std::string attr =
parse_name(beg, end), value;
236 while(isspace(*beg)) ++beg;
242 return {attr, value};
243 }
else throw parse_error(
"attribute missing value in old-style tag");
246 while(isspace(*beg)) ++beg;
247 if(*beg ==
'\'' || *beg ==
'"') {
250 throw parse_error(
"unsupported entity in attribute value");
252 throw parse_error(
"paragraph break in attribute value");
255 value =
t[
"text"].str();
258 std::ostringstream
s;
259 bool found_slash =
false;
260 for(; beg != end && *beg !=
'>' && *beg !=
'<' && !isspace(*beg); ++beg) {
266 if(entity.has_attribute(
"code_point")) {
267 s << unicode_cast<std::string>(entity[
"code_point"].to_int());
269 throw parse_error(
"unsupported entity in attribute value");
271 }
else if(*beg ==
'\\') {
273 }
else if(*beg ==
'/') {
287 if(found_slash) --beg;
289 return {attr, value};
292 static void check_closing_tag(std::string::const_iterator& beg, std::string::const_iterator end, std::string_view match)
294 size_t remaining = end - beg;
295 assert(remaining >= 2 && *beg ==
'<' && *(beg + 1) ==
'/');
296 if(remaining < match.size() + 3) {
297 throw parse_error(
"Unexpected eos in closing tag");
300 if(!std::equal(match.begin(), match.end(), beg)) {
310 static std::pair<std::string, config>
parse_tag(std::string::const_iterator& beg, std::string::const_iterator end);
311 static config parse_tag_contents(std::string::const_iterator& beg, std::string::const_iterator end, std::string_view match,
bool check_for_attributes)
317 for(; check_for_attributes && beg != end && *beg !=
'<'; ++beg) {
318 if(isspace(*beg))
continue;
325 while(beg != end && isspace(*beg)) ++beg;
330 if(beg == end || *beg !=
'<' || (beg + 1) == end || *(beg + 1) !=
'/') {
331 throw parse_error(
"Extra text at the end of old-style tag with explicit 'text' attribute");
337 if(beg == end || *beg !=
'<' || (beg + 1) == end || *(beg + 1) !=
'/') {
338 throw parse_error(
"Extra text at the end of old-style tag with explicit 'text' attribute");
350 if(beg == end || beg + 1 == end) {
354 if(*(beg + 1) ==
'/') {
367 static std::pair<std::string, config>
parse_tag(std::string::const_iterator& beg, std::string::const_iterator end)
372 if(tag_name.empty()) {
375 bool auto_closed =
false;
377 for(; beg != end && *beg !=
'>'; ++beg) {
378 if(isspace(*beg))
continue;
379 if(*beg ==
'/' && (beg + 1) != end && *(beg + 1) ==
'>') {
381 }
else if(isalnum(*beg) || *beg ==
'_') {
384 throw parse_error(
"unexpected eos following attribute");
395 elem[
"text"] = contents[
"text"];
400 return {tag_name, elem};
406 auto beg = text.begin(), end = text.end();
A config object defines a single node in a WML file, with access to child nodes.
void append(const config &cfg)
Append data from another config object to this one.
std::size_t attribute_count() const
Count the number of non-blank attributes.
config & mandatory_child(config_key_type key, int n=0)
Returns the nth child with the given key, or throws an error if there is none.
bool has_child(config_key_type key) const
Determine whether a config has a child or not.
bool has_attribute(config_key_type key) const
std::size_t all_children_count() const
void append_children(const config &cfg)
Adds children from cfg.
optional_config_impl< config > optional_child(config_key_type key, int n=0)
Equivalent to mandatory_child, but returns an empty optional if the nth child was not found.
config & add_child(config_key_type key)
Definitions for the interface to Wesnoth Markup Language (WML).
static std::string parse_name(std::string::const_iterator &beg, std::string::const_iterator end)
static config parse_tag_contents(std::string::const_iterator &beg, std::string::const_iterator end, std::string_view match, bool check_for_attributes)
std::string img(const std::string &src, const std::string &align, bool floating)
Generates a Help markup tag corresponding to an image.
std::string make_link(const std::string &text, const std::string &dst)
Generates a Help markup tag corresponding to a reference or link.
static std::pair< std::string, std::string > parse_attribute(std::string::const_iterator &beg, std::string::const_iterator end, bool allow_empty)
static std::pair< std::string, config > parse_tag(std::string::const_iterator &beg, std::string::const_iterator end)
static char parse_escape(std::string::const_iterator &beg, std::string::const_iterator end)
static config parse_text_until(std::string::const_iterator &beg, std::string::const_iterator end, char close)
std::string tag(std::string_view tag, Args &&... data)
Wraps the given data in the specified formatting tag.
static config parse_entity(std::string::const_iterator &beg, std::string::const_iterator end)
static void check_closing_tag(std::string::const_iterator &beg, std::string::const_iterator end, std::string_view match)
config parse_text(const std::string &text)
Parse a xml style marked up text string.
rect dst
Location on the final composed sheet.
rect src
Non-transparent portion of the surface to compose.
Thrown when the help system fails to parse something.
static map_location::direction n
static map_location::direction s