Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- config parse_text(const std::string& text)
- {
- config res;
- const auto add_text_child =
- [&res](const std::string text) { res.add_child("text", config {"text", text}); };
- bool last_char_escape = false;
- const char escape_char = '\\';
- std::stringstream ss;
- std::size_t pos;
- enum { ELEMENT_NAME, OTHER } state = OTHER;
- for(pos = 0; pos < text.size(); ++pos) {
- const char c = text[pos];
- if(c == escape_char && !last_char_escape) {
- last_char_escape = true;
- } else {
- if(state == OTHER) {
- if(c == '<') {
- if(last_char_escape) {
- ss << c;
- } else {
- add_text_child(ss.str());
- ss.str("");
- state = ELEMENT_NAME;
- }
- } else {
- ss << c;
- }
- } else if(state == ELEMENT_NAME) {
- if(c == '/') {
- throw parse_error("Erroneous / in element name.");
- } else if(c == '>') {
- const std::string element_name = ss.str();
- ss.str("");
- // End of this name.
- // For markup such as "<span color=''>", we only want the first word. If the name
- // has no spaces, the entirety will be used.
- std::stringstream s;
- s << "</" << element_name.substr(0, element_name.find_first_of(' ')) << ">";
- const std::string end_element_name = s.str();
- std::size_t end_pos = text.find(end_element_name, pos);
- if(end_pos == std::string::npos) {
- throw parse_error(formatter() << "Unterminated element: " << element_name);
- }
- const std::string contents = text.substr(pos + 1, end_pos - pos - 1);
- // If we find no '=' character, we assume we're dealing with Pango markup.
- if(contents.find('=') != std::string::npos) {
- s.str(convert_to_wml(element_name, contents));
- s.seekg(0);
- try {
- config cfg;
- read(cfg, s);
- res.append_children(cfg);
- } catch(config::error& e) {
- throw parse_error(formatter() << "Error when parsing help markup as WML: " << e.message);
- }
- } else {
- add_text_child(formatter() << "<" << element_name << ">" << contents << end_element_name);
- }
- pos = end_pos + end_element_name.size() - 1;
- state = OTHER;
- } else {
- ss << c;
- }
- }
- last_char_escape = false;
- }
- }
- if(state == ELEMENT_NAME) {
- throw parse_error(formatter() << "Element '" << ss.str() << "' continues through end of string.");
- }
- // Add the last string.
- if(!ss.str().empty()) {
- res.add_child("text", config{"text", ss.str()});
- }
- return res;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement