int main(int argc, char *argv[]) { std::string str(""); std::string m_str("Top Coder"); std::string n_str("HYU "); char *c_str = " MPPECS\0"; char c = '!'; // Append Operator '+=' str += m_str; std::cout << str << "\n"; // Top Coder str += c_str; std::cout << str << "\n"; // Top Coder MPPECS str += c; std::cout << str << "\n"; // Top Coder MPPECS! str.clear(); // Append Method 'append()' str.append(n_str); std::cout << str << "\n"; // HYU str.append(m_str, 4, 5); std::cout << str << "\n"; // HYU Coder str.append(c_str); std::cout << str << "\n"; // HYU Coder MPPECS str.append(5, c); std::cout << str << "\n"; // HYU Coder MPPECS!!!!! return 0; }
int main(int argc, char *argv[]) { std::string str(""); std::string m_str("ACM-ICPC MPPECS"); std::string n_str(" TOP "); char *c_str("CODER "); char c = '!'; // String Insert str.insert(0, m_str); std::cout << str << "\n"; // ACM-ICPC str.insert(9, n_str, 1, 4); std::cout << str << "\n"; // ACM-ICPC TOP MPPECS str.insert(13, c_str); std::cout << str << "\n"; // ACM-ICPC TOP CODER MPPECS str.insert(25, 5, c); std::cout << str << "\n"; // ACM-ICPC TOP CODER MPPECS!!!!! return 0; }
void ArticleView::append_data_parse_result(const gchar *real_oword, ParseResult& parse_result) { /* Why ParseResultItem's cannot be inserted into the pango_view_ in the * order they appear in the parse_result list? * * They can, but that limits use of the pango markup language when markup * intermixed with objects that are not expressed in pango markup. * For instance we cannot handle the following piece of data: * markup: "<span foreground=\"purple\">some text" * res: some image * markup: "text continues</span>" * The first markup string cannot be committed because it is not a valid * markup - span tag is not closed. But if we piece two markup strings * together, commit markup and then insert the resource, everything will be * fine. * * Here is an outline of the rules parse_result list must adhere to. * * - each list item with pango markup must contain only complete tags. Tag * may not be opened in one list item and closed in another. For example * this list is not allowed: * markup: "<span foreground=\"purple\" " * markup: "size=\"x-large\">" * * - after combining all list items with pango markup the resultant string * must constitute a valid markup (correct order of tags, each tag must have * a corresponding closing tag and so on). For example, the following text * is not allowed: "<b> bla bla </b><i>text end". * Note: list item may contain incomplete markup like "<b>text begins". * * - Delayed insert items must generate only valid markup. Items * representing images, widgets generate a pango-formated error message * if the primary object cannot be inserted. * * * Position in the pango markup string cannot be exactly specified by * character offset only. That is especially important for LabelPangoWidget * where markup is stored in a string. In order to insert delayed insert * items in the correct place it was decided to add a temporary character * in the string in the place where the delayed item must be inserted. * Temporary characters are deleted at the end. * * In addition to character offsets marks are used to specify position in * the text. Marks must be used instead of char offsets when possible. * Marks are preferred over offsets because they preserve position across * text modifications, they have a notion of right and left gravity. * In general we do not know how many character would be inserted in the * text after the call the method insert_pixbuf. Normally it is only one, * but it may be any number in case of error. * * */ Marks marks(pango_view_.get()); std::string start_mark = marks.append_mark(true); std::list<ParseResultItemWithMark> delayed_insert_list; // compose markup { std::string markup_str; int char_offset = 0; const char tmp_char = 'x'; // may be any unicode char excluding '<', '&', '>' for (std::list<ParseResultItem>::iterator it = parse_result.item_list.begin(); it != parse_result.item_list.end(); ++it) { switch (it->type) { case ParseResultItemType_mark: char_offset += xml_utf8_strlen(it->mark->pango.c_str()); markup_str += it->mark->pango; break; case ParseResultItemType_link: { /* links do not insert any text, so exact mark position is * not important. */ ParseResultItemWithMark item(&*it, char_offset); delayed_insert_list.push_back(item); char_offset += xml_utf8_strlen(it->link->pango.c_str()); markup_str += it->link->pango; break; } case ParseResultItemType_res: case ParseResultItemType_widget: { ParseResultItemWithMark item1(NULL, char_offset, true); delayed_insert_list.push_back(item1); char_offset += 1; markup_str += tmp_char; ParseResultItemWithMark item2(&*it, char_offset, true); delayed_insert_list.push_back(item2); char_offset += 1; markup_str += tmp_char; break; } case ParseResultItemType_FormatBeg: case ParseResultItemType_FormatEnd: { /* formats do not insert any text, so exact mark position is * not important. */ ParseResultItemWithMark item2(&*it, char_offset); delayed_insert_list.push_back(item2); break; } default: g_warning("Unsupported item type."); break; } } append_and_mark_orig_word(markup_str, real_oword, LinksPosList()); markup_str.clear(); pango_view_->flush(); } // Marks that precede tmp chars. One mark - one char next to it that must be // deleted. Different marks do not refer to the same char. std::list<std::string> tmp_char_mark_list; // insert marks for(std::list<ParseResultItemWithMark>::iterator it = delayed_insert_list.begin(); it != delayed_insert_list.end(); ) { it->mark = marks.insert_mark(start_mark, it->char_offset, false); if(it->tmp_char) tmp_char_mark_list.push_back(it->mark); if(it->item) ++it; else it = delayed_insert_list.erase(it); } #ifdef DDEBUG std::cout << "ArticleView::append_data_parse_result. marks inserted." << std::endl; #endif // insert delayed items for(std::list<ParseResultItemWithMark>::iterator it = delayed_insert_list.begin(); it != delayed_insert_list.end(); ) { bool EraseCurrent = true; switch(it->item->type) { case ParseResultItemType_link: pango_view_->insert_pango_text_with_links("", it->item->link->links_list, it->mark.c_str()); break; case ParseResultItemType_res: { bool loaded = false; if (it->item->res->type == "image") { append_data_res_image(it->item->res->key, it->mark, loaded); } else if (it->item->res->type == "sound") { append_data_res_sound(it->item->res->key, it->mark, loaded); } else if (it->item->res->type == "video") { append_data_res_video(it->item->res->key, it->mark, loaded); } else { append_data_res_attachment(it->item->res->key, it->mark, loaded); } if (!loaded) { std::string tmark; tmark += "<span foreground=\"red\">"; glib::CharStr m_str(g_markup_escape_text(it->item->res->key.c_str(), -1)); tmark += get_impl(m_str); tmark += "</span>"; pango_view_->insert_pango_text(tmark.c_str(), it->mark.c_str()); } break; } case ParseResultItemType_widget: pango_view_->insert_widget(it->item->widget->widget, it->mark.c_str()); break; case ParseResultItemType_FormatBeg: // change gravity of the mark it->mark = marks.clone_mark(it->mark, true); EraseCurrent = false; break; case ParseResultItemType_FormatEnd: { // find paired ParseResultItemType_FormatBeg item std::list<ParseResultItemWithMark>::reverse_iterator it2(it); for(; it2 != delayed_insert_list.rend(); ++it2) if(it2->item->type == ParseResultItemType_FormatBeg) break; if(it2 != delayed_insert_list.rend() && it2->item->format_beg->type == it->item->format_end->type) { if(it->item->format_end->type == ParseResultItemFormatType_Indent) pango_view_->indent_region(it2->mark.c_str(), 0, it->mark.c_str()); std::list<ParseResultItemWithMark>::iterator it3(it2.base()); delayed_insert_list.erase(--it3); } else g_warning("Not paired ParseResultItemType_FormatEnd item"); break; } default: g_assert_not_reached(); break; } if(EraseCurrent) it = delayed_insert_list.erase(it); else ++it; } // remove tmp chars for(std::list<std::string>::iterator it = tmp_char_mark_list.begin(); it != tmp_char_mark_list.end(); ++it) { #ifdef DDEBUG std::cout << "tmp char mark " << *it << std::endl; #endif pango_view_->delete_text(it->c_str(), 1, 0); } pango_view_->reindent(); if(!delayed_insert_list.empty()) g_warning("delayed_insert_list is not empty. " "parse_result contains not paired items."); }