ustring resource_viewer_produce_anchor(unsigned int book, unsigned int chapter, unsigned int verse) // Produces the anchor, e.g.: Matthew_1_1 or Song_of_Solomon_2_2. { ustring anchor(books_id_to_english(book) + "_" + convert_to_string(chapter) + "_" + convert_to_string(verse)); replace_text(anchor, " ", "_"); return anchor; }
void WindowMerge::copy_master_to_edited_chapter(unsigned int bk, unsigned int ch, bool gui) { // Only copy if the master and edited version differ. This saves a lot of git operations. vector <ustring> master_lines = project_retrieve_chapter(current_master_project, bk, ch); vector <ustring> edited_lines = project_retrieve_chapter(current_edited_project, bk, ch); bool master_is_edited = false; if (master_lines.size() == edited_lines.size()) { master_is_edited = true; for (unsigned int i = 0; i < master_lines.size(); i++) { if (master_lines[i] != edited_lines[i]) { master_is_edited = false; } } } CategorizeChapterVerse ccv(master_lines); if (master_is_edited) { if (gui) gtkw_dialog_info(NULL, _("Both chapters are already the same")); } else { project_store_chapter(current_edited_project, bk, ccv); // A normal snapshot may be removed over time, so we need a persistent one to enable future merges. snapshots_shoot_chapter (current_master_project, bk, ch, 0, true); snapshots_shoot_chapter (current_edited_project, bk, ch, 0, true); if (gui) { ustring message = books_id_to_english(bk) + " " + convert_to_string(ch) + _(" was copied from project ") + current_master_project + _(" to project ") + current_edited_project; gtkw_dialog_info(NULL, message.c_str()); } } }
ustring bibleworks_exported_file_get_bookname(const ustring & filename) // Retrieves the bookname from a file exported by BibleWorks. Though there can // be several books in such a file, this functions retrieves only the name // of the first book. { #define MYMAX 10 ReadText rt(filename, true, false); unsigned int maximum = MYMAX; maximum = CLAMP(maximum, 0, rt.lines.size()); unsigned int goodline = 0; ustring bookname; try { for (unsigned int i = 0; i < maximum; i++) { de_byte_order_mark (rt.lines[i]); ustring bookabbreviation = rt.lines[i].substr(0, 3); unsigned int id = books_bibleworks_to_id(bookabbreviation); if (id) { goodline++; bookname = books_id_to_english(id); } } } catch(exception & ex) { gw_critical(ex.what()); } if (goodline != MYMAX) bookname.clear(); return bookname; #undef MYMAX }
unsigned int bibleworks_clipboard_file_line_get_extract_book_id (ustring& line) // Gets the id of a book from a line of a BibleWorks database copied through the clipboard. // The amount of text that make up the book is removed from the line. // Normally a line of text would look like this: // SCR Matthew 1:1 Βίβλος γενέσεως Ἰησοῦ Χριστοῦ, υἱοῦ Δαβὶδ, υἱοῦ Ἀβραάμ. // or: // SCR 1 Corinthians 1:1 Παῦλος κλητὸς ἀπόστολος Ἰησοῦ Χριστοῦ διὰ θελήματος Θεοῦ, καὶ Σωσθένης ὁ ἀδελφός, { // Remove whitespace from the start of the line. while (line.substr (0, 1) == " ") line.erase (0, 1); // Remove the module abbreviation. size_t pos = line.find (" "); if (pos == string::npos) return 0; line.erase (0, ++pos); // Get the name of the book. vector <unsigned int> ids = books_type_to_ids (btUnknown); for (unsigned int i = 0; i < ids.size(); i++) { ustring english_name = books_id_to_english (ids[i]); if (line.find (english_name) == 0) { line.erase (0, english_name.length()); return ids[i]; } } return 0; }
void ShowNotesDialog::timeout() { // Clear the event id. event_id = 0; // Get the parameters from the dialog, not from the Settings object, since these have not yet been stored. extern Settings * settings; ustring currentreference = books_id_to_english(settings->genconfig.book_get()) + " " + settings->genconfig.chapter_get() + ":" + settings->genconfig.verse_get(); NotesSelectionReferenceType refselection = get_reference_selection (); NotesSelectionEditedType editedselection = get_edited_selection (); ustring category = combobox_get_active_string(combobox_category); if (category == all_categories()) category.clear(); bool currentprojectselection = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobutton_current_project)); // Get notes count. vector <unsigned int> ids; unsigned int id_cursor; notes_select (ids, id_cursor, currentreference, category, refselection, editedselection, currentprojectselection, from_day, to_day); // Update GUI. ustring message = _("This selection would display ") + convert_to_string ((unsigned int)ids.size()) + " "; if (ids.size() == 1) message.append (_("note")); else message.append (_("notes")); gtk_label_set_text (GTK_LABEL (label_result), message.c_str()); }
CheckValidateUsfm::CheckValidateUsfm(const ustring & project, const vector < unsigned int >&books, bool gui, bool checksheet) /* It performs checks related to the USFM standard. project: project to check. books: books to check; if empty it checks them all. gui: whether to show graphical progressbar. checksheet: check whether markers are in the stylesheet of the project. */ { // Init variables. cancelled = false; mychecksheet = checksheet; // Get a list of the books to check. If no books were given, take them all. vector < unsigned int >mybooks(books.begin(), books.end()); if (mybooks.empty()) mybooks = project_get_books(project); // Get all styles in the attached stylesheet. vector <ustring> styless = stylesheet_get_markers(stylesheet_get_actual (), NULL); for (unsigned int i = 0; i < styless.size(); i++) styles.insert(styless[i]); // GUI. progresswindow = NULL; if (gui) { progresswindow = new ProgressWindow(_("Validating markers"), true); progresswindow->set_iterate(0, 1, mybooks.size()); } // Check each book. for (unsigned int bk = 0; bk < mybooks.size(); bk++) { if (gui) { progresswindow->iterate(); progresswindow->set_text(books_id_to_english(book)); if (progresswindow->cancel) { cancelled = true; return; } } book = mybooks[bk]; // Check each chapter. vector <unsigned int> chapters = project_get_chapters(project, book); for (unsigned int ch = 0; ch < chapters.size(); ch++) { chapter = chapters[ch]; vector <ustring> verses = project_get_verses(project, book, chapter); // Check each verse. for (unsigned int vs = 0; vs < verses.size(); vs++) { verse = verses[vs]; ustring line = project_retrieve_verse(project, book, chapter, verse); // Check each line. ParseLine parseline(line); for (unsigned int ln = 0; ln < parseline.lines.size(); ln++) { check(parseline.lines[ln]); } } } } }
void temporal_convert_parallel_passages() // This was used to convert file NT_order_of_OT_Quotations_in_NT.pps to xml. // Then for converting NT_Parallel_Passages.pps. // Then for converting OT_Parallel_Passages.pps. { bool set_opened = false; xmlBufferPtr buffer = xmlBufferCreate(); xmlTextWriterPtr writer = xmlNewTextWriterMemory(buffer, 0); xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL); xmlTextWriterSetIndent(writer, 1); xmlTextWriterStartElement(writer, BAD_CAST "ot-parallel-passages"); ReadText rt("/home/joe/parallel-passages/OT_Parallel_Passages.pps", true); for (unsigned int i = 0; i < rt.lines.size(); i++) { if (rt.lines[i].find("\\key ") == 0) { rt.lines[i].erase(0, 5); xmlTextWriterStartElement(writer, BAD_CAST "section"); xmlTextWriterWriteAttribute(writer, BAD_CAST "title", BAD_CAST rt.lines[i].c_str()); } if (rt.lines[i].find("\\ref ") == 0) { if (!set_opened) { xmlTextWriterStartElement(writer, BAD_CAST "set"); set_opened = true; } xmlTextWriterStartElement(writer, BAD_CAST "reference"); rt.lines[i].erase(0, 5); ustring book, chapter, verse; decode_reference(rt.lines[i], book, chapter, verse); book = books_id_to_english(books_paratext_to_id(book)); xmlTextWriterWriteAttribute(writer, BAD_CAST "book", BAD_CAST book.c_str()); xmlTextWriterWriteAttribute(writer, BAD_CAST "chapter", BAD_CAST chapter.c_str()); xmlTextWriterWriteAttribute(writer, BAD_CAST "verse", BAD_CAST verse.c_str()); xmlTextWriterEndElement(writer); } if (rt.lines[i].empty() || (rt.lines[i].find("\\com") == 0)) { xmlTextWriterEndElement(writer); set_opened = false; } if (rt.lines[i].empty()) { xmlTextWriterEndElement(writer); } } xmlTextWriterEndDocument(writer); xmlTextWriterFlush(writer); g_file_set_contents("/home/joe/ot-parallel-passages.xml", (const gchar *)buffer->content, -1, NULL); if (writer) xmlFreeTextWriter(writer); if (buffer) xmlBufferFree(buffer); }
ustring Reference::human_readable(const ustring & language) // Gives a reference in a human readable format. If no language is given, // it takes the English names of the books. { ustring s; if (language.empty()) s.append(books_id_to_english(book)); else s.append(books_id_to_name(language, book)); s.append(" "); s.append(convert_to_string(chapter)); s.append(":"); s.append(verse); return s; }
void WindowMerge::on_button_merge() { // Settings. extern Settings * settings; // Save all editors. gtk_button_clicked(GTK_BUTTON(save_editors_button)); // Ask what to do. ustring book_chapter = books_id_to_english(book) + " " + convert_to_string(chapter); vector < ustring > labels; labels.push_back(_("Merge ") + book_chapter + _(" of project ") + current_edited_project + _(" and ") + current_master_project); labels.push_back(_("Merge ") + book_chapter + _(" of project ") + current_edited_project + _(" and ") + current_master_project + ",\n" + _("and approve of each change as compared to project ") + current_master_project); labels.push_back(_("Copy ") + book_chapter + _(" of project ") + current_master_project + _(" to project ") + current_edited_project); labels.push_back(_("Copy everything of project ") + current_master_project + _(" to project ") + current_edited_project); RadiobuttonDialog dialog(_("Select action"), _("Select the type of merge or copy to be done"), labels, settings->session.merge_action, false); if (dialog.run() != GTK_RESPONSE_OK) return; // Store action taken. settings->session.merge_action = dialog.selection; // Take the selected action. switch (dialog.selection) { case 0: { merge_edited_into_master(false); break; } case 1: { merge_edited_into_master(true); break; } case 2: { copy_master_to_edited_chapter(book, chapter, true); break; } case 3: { copy_master_to_edited_all(); break; } } // Reload the editors. gtk_button_clicked(GTK_BUTTON(reload_editors_button)); }
CheckChaptersVerses::CheckChaptersVerses(const ustring & project, const vector < unsigned int >&books, bool gui) /* It checks the number of chapters per book and the number of verses per chapter. project: project to check. books: books to check; if empty it checks them all. gui: show graphical progressbar. */ { cancelled = false; myproject = project; extern Settings *settings; ProjectConfiguration *projectconfig = settings->projectconfig(project); myversification = projectconfig->versification_get(); // If no books given, take them all. vector < unsigned int >mybooks(books.begin(), books.end()); if (mybooks.empty()) mybooks = project_get_books(project); progresswindow = NULL; if (gui) { progresswindow = new ProgressWindow(_("Checking chapters and verses"), true); progresswindow->set_iterate(0, 1, mybooks.size()); } for (unsigned int bk = 0; bk < mybooks.size(); bk++) { if (gui) { progresswindow->iterate(); progresswindow->set_text(books_id_to_english(mybooks[bk])); if (progresswindow->cancel) { cancelled = true; return; } } first_chapter_found = false; vector < unsigned int >chapters = project_get_chapters(project, mybooks[bk]); highest_chapter_get(mybooks[bk]); for (unsigned int ch = 0; ch < chapters.size(); ch++) { new_chapter_check(mybooks[bk], chapters[ch]); vector < ustring > verses; verses = project_get_verses(project, mybooks[bk], chapters[ch]); highest_verse_get(mybooks[bk], chapters[ch]); verses_check(mybooks[bk], chapters[ch], verses); } last_chapter_check(mybooks[bk], chapters); } }
map < unsigned int, ustring > resource_get_books2(const ustring & templatefile) { map < unsigned int, ustring > books2; GKeyFile *keyfile = g_key_file_new(); if (g_key_file_load_from_file(keyfile, templatefile.c_str(), G_KEY_FILE_NONE, NULL)) { vector < unsigned int >ids = books_type_to_ids(btUnknown); for (unsigned int i = 0; i < ids.size(); i++) { ustring english_name = books_id_to_english(ids[i]); gchar *value; value = g_key_file_get_string(keyfile, resource_template_books2_group(), english_name.c_str(), NULL); if (value) { books2[i] = value; g_free(value); } } g_key_file_free(keyfile); } return books2; }
void NotesTransferDialog::on_okbutton() { // Get the project. extern Settings *settings; ustring project = settings->genconfig.project_get(); // Progress. ProgressWindow progresswindow(_("Transferring text to notes"), false); // Get the category into which to insert notes. ustring category = combobox_get_active_string(combobox1); // Go through the books in the project. vector < unsigned int >books = project_get_books(project); for (unsigned int bk = 0; bk < books.size(); bk++) { // Progress. progresswindow.set_text(books_id_to_english(books[bk])); // Go through the chapters in this book. Progress. vector < unsigned int >chapters = project_get_chapters(project, books[bk]); progresswindow.set_iterate(0, 1, chapters.size()); for (unsigned int ch = 0; ch < chapters.size(); ch++) { progresswindow.iterate(); // Go through the verses in this chapter. vector < ustring > verses = project_get_verses(project, books[bk], chapters[ch]); for (unsigned int vs = 0; vs < verses.size(); vs++) { // Retrieve each verse and insert it into the notes. ustring text = project_retrieve_verse(project, books[bk], chapters[ch], verses[vs]); clean_note(text); if (!text.empty()) { transfer_note(project, books[bk], chapters[ch], verses[vs], text, category); } } } } }
void SelectBooksDialog::on_okbutton() { // Get the list of books now selected. selection.clear(); vector < ustring > books; gtk_tree_selection_selected_foreach(selectbooks, selection_foreach_function, gpointer(&books)); for (unsigned int i = 0; i < books.size(); i++) { unsigned int book = books_name_to_id(mylanguage, books[i]); if (book) selection.push_back(book); } // Also produce a set out of that list. selectionset.clear(); for (unsigned int i = 0; i < selection.size(); i++) { selectionset.insert(selection[i]); } // If portions are showing, store the values there too. if (myshowportions) { // Get books, includes and portions. vector < ustring > reordered_books; vector < bool > reordered_includes; vector < ustring > reordered_portions; { vector < ustring > books = listview_get_strings(treeviewbooks); for (unsigned int i = 0; i < books.size(); i++) { unsigned int book = books_name_to_id(mylanguage, books[i]); reordered_books.push_back(books_id_to_english(book)); bool include = (selectionset.find(book) != selectionset.end()); reordered_includes.push_back(include); } } reordered_portions = listview_get_strings(treeviewportions); // Save books, includes and portions. extern Settings *settings; ProjectConfiguration *projectconfig = settings->projectconfig(myproject); projectconfig->reordered_books_set(reordered_books); projectconfig->reordered_includes_set(reordered_includes); projectconfig->reordered_portions_set(reordered_portions); } }
void WindowMerge::approval_setup(const ustring & maindata, const ustring & mergedata) { // Initialize the approval system's variables and gui. approve_master_project = current_master_project; approve_edited_project = current_edited_project; approve_book = book; approve_chapter = chapter; ustring label = _("Changes approval, ") + books_id_to_english(approve_book) + " " + convert_to_string(approve_chapter); gtk_label_set_text(GTK_LABEL(label_approve), label.c_str()); gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook1), 1); approve_master_file = gw_build_filename(workingdirectory, "master"); approve_merge_file = gw_build_filename(workingdirectory, "merged"); // Save both sets of data to file. g_file_set_contents(approve_master_file.c_str(), merge_split_data(trim(maindata)).c_str(), -1, NULL); g_file_set_contents(approve_merge_file.c_str(), merge_split_data(trim(mergedata)).c_str(), -1, NULL); // Show differences in the GUI. approval_show_diff(); // Info for user. gtkw_dialog_info(NULL, _("The chapters are ready for approving the individual changes")); }
void mechon_mamre_action_page (HtmlWriter2& htmlwriter) { htmlwriter.heading_open (3); htmlwriter.text_add ("Hebrew import from Mechon Mamre"); htmlwriter.heading_close (); vector <ustring> messages; bool keep_going = true; // Locate the downloaded file. ustring ct005zipfilename = gw_build_filename (g_get_home_dir (), "ct005.zip"); messages.push_back ("Looking for file " + ct005zipfilename); if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) { ct005zipfilename.clear(); } if (ct005zipfilename.empty()) { ct005zipfilename = gw_build_filename (g_get_home_dir (), "Desktop", "ct005.zip"); messages.push_back ("Looking for file " + ct005zipfilename); if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) { ct005zipfilename.clear(); } } if (ct005zipfilename.empty()) { ct005zipfilename = gw_build_filename (g_get_home_dir (), "Downloads", "ct005.zip"); messages.push_back ("Looking for file " + ct005zipfilename); if (!g_file_test (ct005zipfilename.c_str(), G_FILE_TEST_IS_REGULAR)) { ct005zipfilename.clear(); } } if (ct005zipfilename.empty()) { messages.push_back ("Can't find Hebrew input file"); keep_going = false; } if (keep_going) { messages.push_back ("Using file " + ct005zipfilename); } // Unpack the zipped file. ustring directory; if (keep_going) { directory = gw_build_filename (Directories->get_temp (), "uncompress"); unix_rmdir (directory); gw_mkdir_with_parents (directory); if (!uncompress (ct005zipfilename, directory)) { messages.push_back ("Could not unpack the file"); keep_going = false; } messages.push_back ("Unpacking into folder " + directory); } // Show the readme file. if (keep_going) { ustring readmefile = gw_build_filename (directory, "readme.txt"); ReadText rt (readmefile, true, true); ustring line; for (unsigned int i = 0; i < rt.lines.size(); i++) { if (rt.lines[i].empty()) { if (!line.empty()) { messages.push_back (line); line.clear(); } } else { line.append (rt.lines[i] + " "); } } messages.push_back (line); } // Look for the directory where all the html files reside. if (keep_going) { directory = gw_build_filename (directory, "c", "ct"); if (!g_file_test (directory.c_str(), G_FILE_TEST_IS_DIR)) { messages.push_back ("Can't find data in directory " + directory); } messages.push_back ("Looking for data in directory " + directory); } // Get a list of the html files that have the data. vector <ustring> files; if (keep_going) { ReadFiles rf (directory, "c", ".htm"); for (unsigned int i = 0; i < rf.files.size(); i++) { ustring filename = gw_build_filename (directory, rf.files[i]); // Check on a few characteristics. if (mechon_mamre_copyright(filename)) { unsigned int digitcount = digit_count_in_string(rf.files[i]); if ((digitcount == 3) || (digitcount == 4)) { files.push_back(filename); } } } } // Create a new Bible into which to import the data. ustring bible = "Hebrew Mechon Mamre"; if (keep_going) { if (project_exists (bible)) { messages.push_back ("A Bible called \"" + bible + "\" already exists"); keep_going = false; } else { project_create_restore (bible, ""); messages.push_back ("Creating a new Bible called \"" + bible + "\""); // Make a couple of settings. extern Settings * settings; ProjectConfiguration * projectconfig = settings->projectconfig (bible); projectconfig->versification_set ("Original"); projectconfig->editable_set (false); projectconfig->right_to_left_set (true); projectconfig->spelling_check_set (false); } } // Store all the chapters 0 in each book. if (keep_going) { vector <unsigned int> books = books_type_to_ids(btOldTestament); ProgressWindow progresswindow ("Creating books", false); progresswindow.set_iterate (0, 1, books.size()); for (unsigned int bk = 0; bk < books.size(); bk++) { progresswindow.iterate (); vector <ustring> usfm; usfm.push_back ("\\id " + books_id_to_paratext (books[bk])); CategorizeChapterVerse ccv (usfm); project_store_chapter (bible, books[bk], ccv); } } // Store all the chapters. if (keep_going) { ProgressWindow progresswindow ("Importing chapters", false); progresswindow.set_iterate (0, 1, files.size()); for (unsigned int i = 0; i < files.size(); i++) { progresswindow.iterate (); unsigned int book = 0; unsigned int chapter = 0; mechon_mamre_extract_book_chapter (files[i], book, chapter); vector <ustring> contents = mechon_mamre_extract_contents (files[i], chapter); CategorizeChapterVerse ccv (contents); project_store_chapter (bible, book, ccv); messages.push_back ("Importing " + books_id_to_english (book) + " " + convert_to_string (chapter) + " from file " + files[i]); } } // Write accumulated messages. htmlwriter.heading_open (3); if (keep_going) { htmlwriter.text_add ("Success! Bible \"" + bible + "\" was created"); } else { htmlwriter.text_add ("Error!"); } htmlwriter.heading_close (); if (keep_going) { htmlwriter.paragraph_open (); htmlwriter.text_add ("To view the Hebrew text, open the Bible in the editor. Optionally set the font for better display of the Hebrew text. A donation made to Mechon Mamre will support their work."); htmlwriter.paragraph_close (); } for (unsigned int i = 0; i < messages.size(); i++) { htmlwriter.paragraph_open (); htmlwriter.text_add (messages[i]); htmlwriter.paragraph_close (); } // Write OK. htmlwriter.paragraph_open (); htmlwriter.hyperlink_add ("ok", "Ok"); htmlwriter.paragraph_close (); }
void git_resolve_conflict_chapter(const ustring & project, unsigned int book, unsigned int chapter) // This solves a conflicting chapter. { // Log message gw_message(_("Resolving conflict for project ") + project + _(" book ") + books_id_to_english(book) + " " + convert_to_string(chapter)); // Directory of the chapter in the data. ustring directory = project_data_directory_chapter(project, book, chapter); // Data filename. ustring datafile = project_data_filename_chapter(project, book, chapter, false); /* Read the datafile. If there is a conflict it will look like the example below: \c 1 <<<<<<< HEAD:3 John/1/data \v 1 my text. ======= \v 1 server's text. >>>>>>> a62f843ce41ed2d0325c8a2767993df6acdbc933:3 John/1/data \v 2 */ ReadText rt(datafile, true); // Set about to resolve the conflict. vector < ustring > newdata; bool withinmine = false; bool withinserver = false; for (unsigned int i = 0; i < rt.lines.size(); i++) { // Find out when we've a marker, no actual data. bool minemarker = rt.lines[i].find(git_mine_conflict_marker()) != string::npos; bool separatormarker = rt.lines[i] == "======="; bool servermarker = rt.lines[i].find(">>>>>>> ") == 0; // Do conflict management only if we've actual data. bool takeit = false; if (!minemarker && !separatormarker && !servermarker) { if (withinmine) { } else if (withinserver) { takeit = true; } else { takeit = true; } } if (takeit) { newdata.push_back(rt.lines[i]); } else { } // Set whether we're within a conflict, my data, or the server's data. // This setting applies to the next line of data. if (minemarker) { withinmine = true; withinserver = false; } if (separatormarker) { withinmine = false; withinserver = true; } if (servermarker) { withinmine = false; withinserver = false; } } write_lines(datafile, newdata); // Next time that a timed pull and push is done, the conflict will show up as resolved. }
void view_parallel_bible_pdf() { // Log. gw_message(_("Printing Parallel Bible")); // Configuration extern Settings *settings; // Get the chapters and check them. vector < unsigned int >chapters = project_get_chapters(settings->genconfig.project_get(), settings->genconfig.book_get()); if (chapters.empty()) { gtkw_dialog_info(NULL, books_id_to_english(settings->genconfig.book_get()) + _("does not exist in this project")); return; } // Progress system. ProgressWindow progresswindow(_("Parallel Bible"), true); progresswindow.set_text(_("Collecting verses")); progresswindow.set_iterate(0, 1, chapters.size()); // Messages to be printed first. vector < ustring > messages; // All the projects to be put in this parallel Bible. // If the book exists in the project, add it, else give message. vector <ustring> project_s_raw; { vector <ustring> bibles = settings->genconfig.parallel_bible_projects_get(); vector <bool> enabled = settings->genconfig.parallel_bible_enabled_get(); if (bibles.size () == enabled.size()) { for (unsigned int i = 0; i < enabled.size(); i++) { if (enabled[i]) { project_s_raw.push_back (bibles[i]); } } } } vector < ustring > project_names; for (unsigned int i = 0; i < project_s_raw.size(); i++) { if (project_book_exists(project_s_raw[i], settings->genconfig.book_get())) { project_names.push_back(project_s_raw[i]); } else { messages.push_back(_("Project ") + project_s_raw[i] + _(" was requested to be included, but it does not contain ") + books_id_to_english(settings->genconfig.book_get()) + _(". It was left out.")); } } // References to print. vector < Reference > references; // Portion selection. WithinReferencesRange inrange; { vector < unsigned int >portions_chapter_from, portions_chapter_to; vector < ustring > portions_verse_from, portions_verse_to; select_portion_get_values(settings->genconfig.project_get(), settings->genconfig.book_get(), settings->genconfig.parallel_bible_chapters_verses_get(), portions_chapter_from, portions_verse_from, portions_chapter_to, portions_verse_to); inrange.add_portion(settings->genconfig.book_get(), portions_chapter_from, portions_verse_from, portions_chapter_to, portions_verse_to); inrange.set_book(settings->genconfig.book_get()); } // Go through the chapters. for (unsigned int ch = 0; ch < chapters.size(); ch++) { progresswindow.iterate(); inrange.set_chapter(chapters[ch]); // Go through the verse numbers in this chapter. vector < ustring > verses = project_get_verses(settings->genconfig.project_get(), settings->genconfig.book_get(), chapters[ch]); for (unsigned int vs = 0; vs < verses.size(); vs++) { inrange.set_verse(verses[vs]); if (!inrange.in_range()) continue; // See whether to print verses zero. if (!settings->genconfig.parallel_bible_include_verse_zero_get()) if (verses[vs] == "0") continue; // Store the reference. Reference reference(settings->genconfig.book_get(), chapters[ch], verses[vs]); references.push_back(reference); } } // Hide progeressbar. progresswindow.hide(); // Do the printing. ProjectMemory projectmemory(settings->genconfig.project_get(), true); view_parallel_references_pdf(projectmemory, &project_names, references, settings->genconfig.parallel_bible_keep_verses_together_get(), &messages, false); // Log: ready. gw_message(_("Ready printing the Parallel Bible")); }
vector < Reference > search_in_bibledit() // Advanced searching in Bibledit. { // Configuration / session extern Settings *settings; // Set some variables in memory for higher speed. bool casesensitive = settings->session.search_case_sensitive; bool search_current_book = settings->session.search_current_book; bool search_current_chapter = settings->session.search_current_chapter; bool search_globbing = settings->session.search_globbing; bool search_start_word_match = settings->session.search_start_word_match; bool search_end_word_match = settings->session.search_end_word_match; set < unsigned int >selected_books = settings->session.selected_books; AreaType areatype = settings->session.area_type; bool area_id = settings->session.area_id; bool area_intro = settings->session.area_intro; bool area_heading = settings->session.area_heading; bool area_chapter = settings->session.area_chapter; bool area_study = settings->session.area_study; bool area_notes = settings->session.area_notes; bool area_xref = settings->session.area_xref; bool area_verse = settings->session.area_verse; // Progress information. ProgressWindow progresswindow(_("Searching"), true); // The string to search for. // Note any apostrophies need to be doubled for SQLite. // We need to normalize the search expression when comparing strings. ustring localsearchword(settings->session.searchword.normalize()); if (!casesensitive) localsearchword = localsearchword.casefold(); ustring localsearchword2(localsearchword); // Storage for references: search results. vector < Reference > results; // Get our position in the text. ustring project = settings->genconfig.project_get(); ustring book = books_id_to_english(settings->genconfig.book_get()); unsigned int chapter = convert_to_int(settings->genconfig.chapter_get()); // Go through each book in the project. Progress information. vector < unsigned int >availablebooks = project_get_books(project); progresswindow.set_iterate(0, 1, availablebooks.size()); for (unsigned int bk = 0; bk < availablebooks.size(); bk++) { progresswindow.iterate(); if (progresswindow.cancel) { return results; } // If the book is not to be searched, skip it. if (search_current_book) if (book != books_id_to_english(availablebooks[bk])) continue; if (selected_books.find(availablebooks[bk]) == selected_books.end()) continue; try { // Go through each chapter in the book. vector < unsigned int >chapters = project_get_chapters(project, availablebooks[bk]); for (unsigned int ch = 0; ch < chapters.size(); ch++) { // Do we search this chapter? if (search_current_chapter) if (chapter != chapters[ch]) continue; // Read the chapter. vector < ustring > lines = project_retrieve_chapter(project, availablebooks[bk], chapters[ch]); CategorizeChapterVerse ccv(lines); // Go through the verses. for (unsigned int i = 0; i < ccv.verse.size(); i++) { // Verse number. ustring verse = ccv.verse[i]; // Handle casesensitive and area selection. // Assemble text to search through. ustring input(ccv.line[i]); if (!casesensitive) input = input.casefold(); ustring text = search_in_bibledit_assemble_line(input, areatype, area_id, area_intro, area_heading, area_chapter, area_study, area_notes, area_xref, area_verse); // Use glob-style pattern matching or straight match. if (search_globbing) { ustring patternword = "*" + localsearchword + "*"; if (!g_pattern_match_simple(patternword.c_str(), text.c_str())) continue; } else { if (text.find(localsearchword) == string::npos) continue; } // Do the word boundary matching. if (!search_in_bibledit_word_boundaries_match(text, localsearchword, search_start_word_match, search_end_word_match, search_globbing)) continue; // This verse "passed" all tests: a search result. Reference reference(availablebooks[bk], chapters[ch], verse); results.push_back(reference); } } } catch(exception & ex) { gw_critical(ex.what()); } } // Give the results. return results; }
void XeTeX::write_document_tex_file () { // Settings. extern Settings * settings; ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get()); // Style sheet. extern Styles * styles; Stylesheet * sheet = styles->stylesheet (stylesheet_get_actual ()); document_tex.push_back (_("% Configuration file created by Bibledit-Gtk")); document_tex.push_back (_("% You can modify it to suit your needs")); document_tex.push_back (_("% After modification, run the following command in this directory:")); document_tex.push_back (_("% xetex document.tex")); document_tex.push_back (_("% After that look carefully at the output")); document_tex.push_back (_("% If it says that a re-run is required, repeat this command")); document_tex.push_back (""); document_tex.push_back (_("% Include the ptx2pdf macros")); document_tex.push_back ("\\input paratext2.tex"); document_tex.push_back (""); document_tex.push_back (_("% Paper size")); document_tex.push_back ("\\PaperWidth=" + convert_to_string (settings->genconfig.paper_width_get()) + "cm"); document_tex.push_back ("\\PaperHeight=" + convert_to_string (settings->genconfig.paper_height_get()) + "cm"); if (settings->session.print_crop_marks){ document_tex.push_back (""); document_tex.push_back (_("% Crop marks")); document_tex.push_back ("\\CropMarkstrue"); } document_tex.push_back (""); document_tex.push_back (_("% The basic unit for the margins; changing this will alter them all")); document_tex.push_back ("\\MarginUnit=1cm"); document_tex.push_back (""); document_tex.push_back (_("% Relative sizes of margins, based on the unit above")); document_tex.push_back ("\\def\\TopMarginFactor{" + convert_to_string (settings->genconfig.paper_top_margin_get()) + "}"); document_tex.push_back ("\\def\\BottomMarginFactor{" + convert_to_string (settings->genconfig.paper_bottom_margin_get()) + "}"); document_tex.push_back ("\\def\\SideMarginFactor{" + convert_to_string (settings->genconfig.paper_outside_margin_get()) + "}"); if (settings->genconfig.paper_inside_margin_get() != settings->genconfig.paper_outside_margin_get()) { document_tex.push_back (""); document_tex.push_back (_("% Extra margin for the gutter on the binding side")); document_tex.push_back ("\\BindingGuttertrue"); document_tex.push_back ("\\BindingGutter=" + convert_to_string (settings->genconfig.paper_inside_margin_get() - settings->genconfig.paper_outside_margin_get()) + "cm"); document_tex.push_back (""); document_tex.push_back (_("% Double sided printing")); document_tex.push_back ("\\DoubleSidedtrue"); } if (!projectconfig->editor_font_default_get()) { PangoFontDescription *font_desc = pango_font_description_from_string(projectconfig->editor_font_name_get().c_str()); if (font_desc){ // Assemble the string for the font mapping. ustring font_mapping = projectconfig->xetex_font_mapping_file_get(); if (!font_mapping.empty()) { if (g_str_has_suffix (font_mapping.c_str(), ".tec")) { font_mapping = gw_path_get_basename (font_mapping); // Remove the .tec suffix. font_mapping.erase (font_mapping.length() - 4, 4); // Insert the mapping command. font_mapping.insert (0, "mapping="); } else { gw_warning (_("Font mapping file ") + font_mapping + _(" should have the .tec suffix - ignoring this file")); font_mapping.clear(); } } // Assemble the string for the shaping engine. ustring shaping_engine; switch (XeTeXScriptingEngineType (projectconfig->xetex_shaping_engine_get())) { case xtxsetGeneric: break; case xtxsetArab: shaping_engine = "script=arab"; break; } // Assemble the addition to the font. ustring font_addition; if (!font_mapping.empty()) { if (font_addition.empty()) font_addition.append (":"); else font_addition.append (";"); font_addition.append (font_mapping); } if (!shaping_engine.empty()) { if (font_addition.empty()) font_addition.append (":"); else font_addition.append (";"); font_addition.append (shaping_engine); } ustring font_family = pango_font_description_get_family (font_desc); document_tex.push_back (""); document_tex.push_back (_("% Fonts to use for \"plain\", \"bold\", \"italic\", and \"bold italic\" from the stylesheet")); document_tex.push_back (_("% (they need not really be italic, etc.)")); document_tex.push_back (_("% Add e.g. \":mapping=farsidigits\" to get digits in Farsi, provided the farsidigits.tec TECkit mapping is available")); document_tex.push_back (_("% Add e.g. \":script=arab\" to use the arab shaping engine instead of the generic one")); document_tex.push_back ("\\def\\regular{\"" + font_family + font_addition + "\"}"); document_tex.push_back ("\\def\\bold{\"" + font_family + "/B" + font_addition + "\"}"); document_tex.push_back ("\\def\\italic{\"" + font_family + "/I" + font_addition + "\"}"); document_tex.push_back ("\\def\\bolditalic{\"" + font_family + "/BI" + font_addition + + "\"}"); pango_font_description_free(font_desc); } } if (projectconfig->right_to_left_get()) { document_tex.push_back (""); document_tex.push_back (_("% Right-to-left layout mode")); document_tex.push_back ("\\RTLtrue"); } document_tex.push_back (""); document_tex.push_back (_("% The unit for font sizes in the stylesheet; changing this will scale all text proportionately")); document_tex.push_back ("\\FontSizeUnit=1pt"); document_tex.push_back (""); document_tex.push_back (_("% Scaling factor used to adjust line spacing, relative to font size")); double line_spacing_factor = 1.0; double vertical_space_factor = 1.0; if (!projectconfig->editor_font_default_get()){ line_spacing_factor = projectconfig->text_line_height_get() / 100; vertical_space_factor = projectconfig->text_line_height_get() / 100; } document_tex.push_back ("\\def\\LineSpacingFactor{" + convert_to_string (line_spacing_factor) + "}"); document_tex.push_back ("\\def\\VerticalSpaceFactor{" + convert_to_string (vertical_space_factor) + "}"); document_tex.push_back (""); document_tex.push_back (_("% Information to include in the running header (at top of pages, except first)")); document_tex.push_back (_("% We set the items to print at left/center/right of odd and even pages separately")); document_tex.push_back (_("% Possible contents:")); document_tex.push_back (_("% \\rangeref = Scripture reference of the range of text on the page;")); document_tex.push_back (_("% \\firstref = reference of the first verse on the page)")); document_tex.push_back (_("% \\lastref = reference of the last verse on the page)")); document_tex.push_back (_("% \\pagenumber = the page number")); document_tex.push_back (_("% \\empty = print nothing in this position")); document_tex.push_back ("\\def\\RHoddleft{\\empty}"); document_tex.push_back ("\\def\\RHoddcenter{\\empty}"); document_tex.push_back ("\\def\\RHoddright{\\rangeref}"); document_tex.push_back (""); document_tex.push_back ("\\def\\RHevenleft{\\rangeref}"); document_tex.push_back ("\\def\\RHevencenter{\\empty}"); document_tex.push_back ("\\def\\RHevenright{\\empty}"); document_tex.push_back (""); document_tex.push_back ("\\def\\RHtitleleft{\\empty}"); document_tex.push_back ("\\def\\RHtitlecenter{\\empty}"); document_tex.push_back ("\\def\\RHtitleright{\\empty}"); document_tex.push_back (""); document_tex.push_back ("\\def\\RFoddcenter{\\pagenumber}"); document_tex.push_back ("\\def\\RFevencenter{\\pagenumber}"); document_tex.push_back ("\\def\\RFtitlecenter{\\pagenumber}"); document_tex.push_back (""); document_tex.push_back (_("% Whether to include verse number in running head, or only chapter")); document_tex.push_back ("\\VerseRefstrue"); document_tex.push_back (""); document_tex.push_back (_("% Whether to skip printing verse number 1 at start of chapter")); document_tex.push_back ("\\OmitVerseNumberOnetrue"); document_tex.push_back (""); document_tex.push_back (_("% Whether to use paragraph indent at drop-cap chapter numbers")); document_tex.push_back (_("% \\IndentAtChaptertrue")); // Go through the stylesheet looking for note markers. for (unsigned int i = 0; i < sheet->styles.size(); i++) { bool retrieve_note_data = false; StyleV2 * style = sheet->styles[i]; if (style->type == stFootEndNote) { if ((style->subtype == fentFootnote) || (style->subtype == fentEndnote)) { retrieve_note_data = true; } } if ((style->type == stFootEndNote) || (style->type == stCrossreference)) { if (style->subtype == ctCrossreference) { retrieve_note_data = true; } } if (retrieve_note_data) { ustring marker = style->marker; document_tex.push_back (""); document_tex.push_back (_("% Reformat \\") + marker + " notes as a single paragraph"); document_tex.push_back ("\\ParagraphedNotes{" + marker + "}"); document_tex.push_back (""); NoteNumberingType note_numbering = NoteNumberingType (style->userint1); switch (note_numbering) { case nntNumerical: document_tex.push_back (_("% Numerical callers for \\") + marker + _(" notes")); document_tex.push_back ("\\NumericCallers{" + marker + "}"); break; case nntAlphabetical: document_tex.push_back (_("% Alphabetical callers for \\") + marker + _(" notes")); document_tex.push_back ("\\AutoCallers{" + marker+ "}{a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z}"); break; case nntUserDefined: ustring autocallers; for (unsigned int i = 0; i < style->userstring1.size(); i++) { if (i) autocallers.append (","); autocallers.append (style->userstring1.substr (i, 1)); } if (!autocallers.empty()) { document_tex.push_back (_("% Special caller sequence for \\") + marker + " notes"); document_tex.push_back ("\\AutoCallers{" + marker+ "}{" + autocallers + "}"); } break; } document_tex.push_back (""); NoteNumberingRestartType note_restart = NoteNumberingRestartType (style->userint2); switch (note_restart) { case nnrtNever: break; case nnrtBook: break; case nnrtChapter: break; } document_tex.push_back (_("% Reset callers every page for \\") + marker + _(" notes")); document_tex.push_back ("\\PageResetCallers{" + marker + "}"); document_tex.push_back (""); document_tex.push_back (_("% Omit callers in the note for \\") + marker + _(" notes")); document_tex.push_back (_("% \\OmitCallerInNote{") + marker + "}"); } } document_tex.push_back (""); document_tex.push_back (_("% The number of columns")); document_tex.push_back ("\\TitleColumns=1"); document_tex.push_back ("\\IntroColumns=1"); document_tex.push_back ("\\BodyColumns=2"); document_tex.push_back (""); document_tex.push_back (_("% The gutter between double cols, relative to font size")); document_tex.push_back ("\\def\\ColumnGutterFactor{15}"); // Define the Paratext stylesheet to be used as a basis for formatting write_stylesheet (); // Write the data and add their filenames. for (unsigned int i = 0; i < book_ids.size(); i++) { ustring filename = convert_to_string (book_ids[i]) + " " + books_id_to_english(book_ids[i]) + ".usfm"; replace_text (filename, " ", "_"); write_lines (gw_build_filename (working_directory, filename), book_data[i]); document_tex.push_back ("\\ptxfile{" + filename + "}"); } // End of document input. document_tex.push_back ("\\end"); // Write document.text to file. write_lines (gw_build_filename (working_directory, "document.tex"), document_tex); }
CheckParallelPassages::CheckParallelPassages(bool nt, const ustring & project, const vector < unsigned int >&books, bool includetext, bool gui,const ustring & project2) { // Language. extern Settings *settings; ustring language = settings->projectconfig(project, false)->language_get(); // Mapping. ustring versification = settings->projectconfig(project, false)->versification_get(); Mapping mapping(versification, 0); // Get a list of the books to check. If no books were given, take them all. vector < unsigned int >mybooks(books.begin(), books.end()); if (mybooks.empty()) mybooks = project_get_books(project); set < unsigned int >bookset(mybooks.begin(), mybooks.end()); // Get the parallel passages. OtNtParallels otntparallels(0); if (nt) otntparallels.readnt(); else otntparallels.readot(); // GUI. progresswindow = NULL; if (gui) { progresswindow = new ProgressWindow(_("Producing passages"), true); progresswindow->set_iterate(0, 1, otntparallels.sections.size()); } // Go through each section. for (unsigned int i = 0; i < otntparallels.sections.size(); i++) { if (gui) { progresswindow->iterate(); if (progresswindow->cancel) return; } OtNtParallelDataSection datasection(0); // Section's heading. datasection.title = otntparallels.sections[i].title; // Go through each set of references. for (unsigned int i2 = 0; i2 < otntparallels.sections[i].sets.size(); i2++) { // Go through the references in the set. OtNtParallelDataSet dataset(0); for (unsigned int i3 = 0; i3 < otntparallels.sections[i].sets[i2].references.size(); i3++) { // Skip if NT book is not to be included. if (bookset.find(otntparallels.sections[i].sets[i2].references[i3].book) == bookset.end()) continue; vector < int >remapped_chapter; vector < int >remapped_verse; mapping.book_change(otntparallels.sections[i].sets[i2].references[i3].book); mapping.original_to_me(otntparallels.sections[i].sets[i2].references[i3].chapter, otntparallels.sections[i].sets[i2].references[i3].verse, remapped_chapter, remapped_verse); Reference mapped_reference(otntparallels.sections[i].sets[i2].references[i3].book, remapped_chapter[0], convert_to_string(remapped_verse[0])); ustring verse = mapped_reference.human_readable(language); if (includetext) { verse.append(" "); verse.append(usfm_get_verse_text_only(project_retrieve_verse(project, mapped_reference.book, mapped_reference.chapter, mapped_reference.verse))); } dataset.data.push_back(verse); references.push_back(books_id_to_english(mapped_reference.book) + " " + convert_to_string(mapped_reference.chapter) + ":" + mapped_reference.verse); comments.push_back(_("Parallel")); } datasection.sets.push_back(dataset); //output verses of second project OtNtParallelDataSet dataset2(0); //TODO refactor this loop into a separate function if (project2!="") { ustring language2 = settings->projectconfig(project2, false)->language_get(); // Mapping. ustring versification2 = settings->projectconfig(project2, false)->versification_get(); Mapping mapping2(versification2, 0); for (unsigned int i3 = 0; i3 < otntparallels.sections[i].sets[i2].references.size(); i3++) { // Skip if NT book is not to be included. if (bookset.find(otntparallels.sections[i].sets[i2].references[i3].book) == bookset.end()) continue; vector < int >remapped_chapter; vector < int >remapped_verse; mapping2.book_change(otntparallels.sections[i].sets[i2].references[i3].book); mapping2.original_to_me(otntparallels.sections[i].sets[i2].references[i3].chapter, otntparallels.sections[i].sets[i2].references[i3].verse, remapped_chapter, remapped_verse); Reference mapped_reference(otntparallels.sections[i].sets[i2].references[i3].book, remapped_chapter[0], convert_to_string(remapped_verse[0])); ustring verse = mapped_reference.human_readable(language); if (includetext) { verse.append(" "); verse.append(usfm_get_verse_text_only(project_retrieve_verse(project2, mapped_reference.book, mapped_reference.chapter, mapped_reference.verse))); } dataset2.data.push_back(verse); references.push_back(books_id_to_english(mapped_reference.book) + " " + convert_to_string(mapped_reference.chapter) + ":" + mapped_reference.verse); comments.push_back(_("Parallel")); } datasection.sets.push_back(dataset2); } } data.push_back(datasection); } }
void CheckChaptersVerses::message(unsigned int book, unsigned int chapter, const ustring & verse, const ustring & message) { references.push_back(books_id_to_english(book) + " " + convert_to_string(chapter) + ":" + verse); comments.push_back(message); }
void CheckValidateUsfm::message(const ustring & message) { references.push_back(books_id_to_english(book) + " " + convert_to_string(chapter) + ":" + verse); comments.push_back(message); }
void notes_store_index_entry (sqlite3 *db, gint32 id) { gchar *sql; // Delete optional previous entry with "id". sql = g_strdup_printf("delete from notes where id = %d;", id); sqlite3_exec(db, sql, NULL, NULL, NULL); g_free(sql); // Read the note with "id". ustring note; ustring project; ustring references; ustring category; int date_created; ustring user_created; int date_modified; ustring logbook; notes_read_one_from_file (id, note, project, references, category, date_created, user_created, date_modified, logbook); // Bail out if there's no note. if (note.empty()) { return; } // Attend to the id: use variable "id". // Attend to the encoded references. Parse parse(references, false); ustring encoded_references; for (unsigned int i = 0; i < parse.words.size(); i++) { Reference oldRef; Reference newRef; reference_discover(oldRef, parse.words[i], newRef); ustring book = books_id_to_english(newRef.book_get()); ustring chapter = convert_to_string(newRef.chapter_get()); vector < int >verses = verses_encode(newRef.verse_get()); int book_chapter = reference_to_numerical_equivalent(book, chapter, "0"); for (unsigned int i2 = 0; i2 < verses.size(); i2++) { encoded_references.append(" "); encoded_references.append(convert_to_string(int (book_chapter + verses[i2]))); } } encoded_references.append(" "); // Attend to the project: use variable "project". // Apostrophies need to be doubled before storing them. project = double_apostrophy(project); // Attend to the category: use variable "category". // Apostrophies need to be doubled before storing them. category = double_apostrophy(category); // Attend to the note text in case folded form // Apostrophies need to be doubled before storing them. note = note.casefold (); note = double_apostrophy(note); // Attend to the date created: use variable "date_created". // Attend to the date modified: use variable "date_modified". // Put new data in the database. sql = g_strdup_printf("insert into notes values (%d, '%s', '%s', '%s', '%s', %d, %d);", id, encoded_references.c_str(), project.c_str(), category.c_str(), note.c_str(), date_created, date_modified); sqlite3_exec(db, sql, NULL, NULL, NULL); g_free(sql); }
void Wordlist::run(vector < ustring > &allmessages) { // No project given: bail out. if (project.empty()) { message(_("No project")); return; } // Pass 1: Collect words and handle asterisks. // Go through the books. vector < unsigned int >books = project_get_books(project); progresswindow->set_iterate(0, 1, books.size()); for (unsigned int bk = 0; bk < books.size(); bk++) { progresswindow->iterate(); // Go through the chapters. vector < unsigned int >chapters = project_get_chapters(project, books[bk]); for (unsigned int ch = 0; ch < chapters.size(); ch++) { // Go through the lines of the chapter, and process them. vector <ustring> lines = project_retrieve_chapter(project, books[bk], chapters[ch]); set <ustring> section_entries; bool chapter_content_was_changed = false; for (unsigned int i = 0; i < lines.size(); i++) { ustring line(lines[i]); process_line(line, section_entries); if (line != lines[i]) { chapter_content_was_changed = true; lines[i] = line; } } if (chapter_content_was_changed) { CategorizeChapterVerse ccv(lines); project_store_chapter(project, books[bk], ccv); } } } // Informative messages. message(_("Total entries: ") + convert_to_string(wordcount)); message(_("Unique entries: ") + convert_to_string((unsigned int)words.size())); // Pass 2: Insert word lists. // Only proceed if there is something to insert. if (!words.empty()) { // Whether a list was inserted. bool inserted = false; // Go through the books. progresswindow->set_iterate(0, 1, books.size()); for (unsigned int bk = 0; bk < books.size(); bk++) { progresswindow->iterate(); // Go through the chapters. vector < unsigned int >chapters = project_get_chapters(project, books[bk]); for (unsigned int ch = 0; ch < chapters.size(); ch++) { // Go through the lines of the chapter to look for the position to insert the list. unsigned int opener_offset = 0; unsigned int closer_offset = 0; vector < ustring > lines = project_retrieve_chapter(project, books[bk], chapters[ch]); for (unsigned int ln = 0; ln < lines.size(); ln++) { if (lines[ln].find(list_opener) == 0) { opener_offset = ln; } if (lines[ln].find(list_closer) == 0) { closer_offset = ln; } } // If something like a position was found, process that. if (opener_offset || closer_offset) { if (opener_offset && closer_offset && (opener_offset < closer_offset)) { insert_list(lines, opener_offset, closer_offset); CategorizeChapterVerse ccv(lines); project_store_chapter(project, books[bk], ccv); message(_("Word list inserted in ") + books_id_to_english(books[bk]) + " " + convert_to_string(chapters[ch])); inserted = true; } else { message(_("Invalid word list location in ") + books_id_to_english(books[bk]) + " " + convert_to_string(chapters[ch])); } } } } // Message if the list was not inserted. if (!inserted) message(_("No place found to insert the word list")); } // Store messages. for (unsigned int i = 0; i < messages.size(); i++) { allmessages.push_back(messages[i]); } }