void MergeDialog::preprocess_empty_replacements(ustring & text) /* There are cases that one text is completely removed in a conflict situation. The replacement for this text is empty. In the merge routine this shows as: <<<<<<< /home/joe/.bibledit_temp/merge/file1 servant of Jesus Christ and ======= >>>>>>> /home/joe/.bibledit_temp/merge/file3 And in the internal texts this shows as: __conflict__marker__before__ servant of Jesus Christ and __conflict__marker__middle__ __conflict__marker__after__ This function handles this case so that it does not lead to confusion. */ { replace_text(text, merge_conflict_markup(1) + " " + merge_conflict_markup(2), merge_conflict_markup(1) + " " + merge_conflict_markup(2)); replace_text(text, merge_conflict_markup(2) + " " + merge_conflict_markup(3), merge_conflict_markup(2) + " " + merge_conflict_markup(3)); }
ustring shell_clean_filename(const ustring & filename) // Replace characters like ' and / occur in the filename with _. { ustring cleanfile(filename); replace_text(cleanfile, "'", "_"); replace_text(cleanfile, "/", "_"); return cleanfile; }
ustring resource_url_enter_reference(const ustring& constructor, map <unsigned int, ustring>& books, map <unsigned int, ustring>& books2, const Reference& reference) { ustring url (constructor); replace_text(url, resource_url_constructor_book(), books[reference.book_get()]); replace_text(url, resource_url_constructor_book2(), books2[reference.book_get()]); replace_text(url, resource_url_constructor_chapter(), convert_to_string(reference.chapter_get())); replace_text(url, resource_url_constructor_verse(), number_in_string(reference.verse_get())); return url; }
void MergeDialog::on_okbutton() { GtkTextIter startiter, enditer; gtk_text_buffer_get_start_iter(textbuffer, &startiter); gtk_text_buffer_get_end_iter(textbuffer, &enditer); reconciled_text = gtk_text_buffer_get_text(textbuffer, &startiter, &enditer, false); replace_text(reconciled_text, " ", " "); replace_text(reconciled_text, " ", " "); }
void MergeDialog::on_okbutton() { GtkTextIter startiter, enditer; gtk_text_buffer_get_start_iter(textbuffer, &startiter); gtk_text_buffer_get_end_iter(textbuffer, &enditer); gchar *txt = gtk_text_buffer_get_text(textbuffer, &startiter, &enditer, false); reconciled_text = txt; g_free(txt); // Postiff: plug memory leak replace_text(reconciled_text, " ", " "); replace_text(reconciled_text, " ", " "); }
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 FindBar::on_replace_all_clicked() { auto text = find_entry_->get_text(); auto replacement_text = replace_entry_->get_text(); /* * This is either clever or stupid... * * Basically, we can't just call locate_matches * and then iterate them because replacing the first will invalidate * all the iterators. So we have to call locate_matches after each replacement * until all the matches are gone. But there is an edge case, if we have a case-insensitive * match, and we replace the same text but with different capitalization (e.g. replace * 'cheese' with 'CHEESE') then the number of matches never changes, even when the replacements * happen - so we'd hit an infinte loop. So what we do is we keep track of the number of matches * if the number of matches changes (goes down) then we don't increment i to read the next match * we just keep replacing matches_[0] till they are all gone. If the number of matches doesn't change * then we increment 'i' each time so we eventually replace all the matches even if they are the same * case! Phew!! */ locate_matches(unicode(text.c_str())); uint32_t i = 0; uint32_t last_matches_size = matches_.size(); while(!matches_.empty() && i < matches_.size()) { replace_text(matches_[i].first, matches_[i].second, replacement_text); locate_matches(unicode(text.c_str())); if(matches_.size() == last_matches_size) { ++i; } } }
void Wordlist::process_line(ustring & line, set <ustring> §ion_entries) // Processes one line of text: // - deals with entries. // - deals with asterisks. // section_entries - has the entries already made in this section. { // Handle section restart. { ustring s (line); ustring marker = usfm_extract_marker (s); if (section_markers.find (marker) != section_markers.end()) { section_entries.clear(); } } // Remove the asterisk before and the asterisk after the closer, e.g.: // \w entry*\w* -> \w entry\w* // \w entry\w** -> \w entry\w* replace_text(line, "*" + entry_closer, entry_closer); replace_text(line, entry_closer + "*", entry_closer); // Go through the line looking for the opener. size_t startpos = line.find(entry_opener); while (startpos != string::npos) { // Look for the closer too, after the opener, not before. size_t endpos = line.find(entry_closer, startpos); if (endpos == string::npos) break; // Get the word. ustring word = line.substr(startpos + entry_opener.length(), endpos - startpos - entry_closer.length()); if (!word.empty()) { // Store the word. words.insert(word); wordcount++; // Handle asterisks. if (use_asterisk) { bool insert_asterisk = true; if (first_in_chapter) if (section_entries.find(word) != section_entries.end()) insert_asterisk = false; if (insert_asterisk) { line.insert(endpos + entry_closer.length(), "*"); } section_entries.insert(word); } } startpos = line.find(entry_opener, endpos); } }
void TextWidget::paste() { if (!gui_window->clipboard_has_string()) return; int start, end; get_cursor_slice(start, end); String str = gui_window->get_clipboard_string(); replace_text(start, end, str, str.length()); }
void TextWidget::on_text_input(const TextInputEvent *event) { if (!_text_interaction_on) return; int start, end; get_cursor_slice(start, end); String one_char; one_char.append(event->codepoint); replace_text(start, end, one_char, 1); }
void odt_set_font(const ustring & directory, const ustring & fontname) // Writes the font to the right files in the directory given. { // Save the font in the content file. ReadText rt2(odt_content_xml_filename(directory), true, false); for (unsigned int i = 0; i < rt2.lines.size(); i++) { replace_text(rt2.lines[i], "Bitstream", fontname); } write_lines(odt_content_xml_filename(directory), rt2.lines); }
bool bibleworks_reference_get_decode (ustring response, Reference& reference) { // If BibleWorks was not running it might get started at this point, but the value it returns is empty as a result of a timeout. if (response.empty()) return false; // The response could be, e.g.: "OK Jer 39:10" (without the quotes). replace_text (response, ":", " "); Parse parse (response); if (parse.words.size() != 4) return false; reference.book = books_bibleworks_to_id (parse.words[1]); reference.chapter = convert_to_int (parse.words[2]); reference.verse = parse.words[3]; return true; }
void GwSpawn::arg(ustring value) // Add one arguments to the arguments for running the program. // This function can be repeated as many times as desired. { #ifdef WIN32 // Quote the argument. value = shell_quote_space(value); #else // Escape any '. replace_text(value, "'", "\\'"); // We do not shell_quote_space this argument because // we are not executing this through a shell. GwSpawnpawn::run // passes arguments directly through argv[]. #endif // Save argument. myarguments.push_back(value); }
void FindBar::on_replace_clicked() { auto text = find_entry_->get_text(); auto replacement_text = replace_entry_->get_text(); if(text == replacement_text) { //no-op return; } std::pair<Gtk::TextIter, Gtk::TextIter> to_replace; if(last_selected_match_ > -1 && !matches_.empty()) { //If we had a selected match already, then replace that before moving on to_replace = matches_[last_selected_match_]; replace_text(to_replace.first, to_replace.second, replacement_text); } //Find the next match on_find_next_clicked(); }
void notes_display_internal(const ustring& language, bool show_reference_text, bool show_summary, ustring& note_buffer, unsigned int id, const gchar * text, unsigned int cursor_id, unsigned int &cursor_offset) { // Optionally display the extra text. if (text) { note_buffer.append(text); note_buffer.append("<BR>\n"); } // Get data from the note file. ustring note; ustring project; ustring reference; ustring category; int date_created; ustring user_created; int date_modified; ustring logbook; notes_read_one_from_file (id, note, project, reference, category, date_created, user_created, date_modified, logbook); // Parse the reference(s) string into its possible several references. Parse parse(reference, false); reference.clear(); // Keep list of references. vector <Reference> references; // Go through each reference. for (unsigned int i2 = 0; i2 < parse.words.size(); i2++) { // Make it human readable. Reference oldRef; Reference newRef; reference_discover(oldRef, parse.words[i2], newRef); if (!reference.empty()) { reference.append(", "); } reference.append(newRef.human_readable(language)); references.push_back(newRef); } // Start creating the heading with links. ustring linkheading; // If this note is to be focused, then insert a special anchor for that: // <a name="cursoranchor" id="cursoranchor"></a> if (id == cursor_id) { linkheading.append ("<a name=\""); linkheading.append (notes_cursor_anchor()); linkheading.append ("\" id=\""); linkheading.append (notes_cursor_anchor()); linkheading.append ("\"></a>"); } extern Settings * settings; if (settings->session.project_notes_show_title) { // Insert a link with this heading, e.g.: <a href="10">Genesis 1.1</a> linkheading.append("<a href=\"" + convert_to_string(id) + "\">"); linkheading.append(reference); if (settings->genconfig.notes_display_project_get()) linkheading.append(" " + project); if (settings->genconfig.notes_display_category_get()) linkheading.append(" " + category); if (settings->genconfig.notes_display_date_created_get()) linkheading.append(" " + date_time_julian_human_readable(date_created, true)); if (settings->genconfig.notes_display_created_by_get()) linkheading.append(" " + user_created); linkheading.append("</a>"); // Append a [delete] link too, e.g.: <a href="d10">[delete]</a> linkheading.append(" <a href=\"d" + convert_to_string(id) + "\">"); linkheading.append("[delete]"); linkheading.append("</a>"); // Append a [references] link too, e.g.: <a href="r10">[references]</a> linkheading.append(" <a href=\"r" + convert_to_string(id) + "\">"); linkheading.append("[references]"); linkheading.append("</a>"); } // Add the heading to the note data. note_buffer.append(linkheading); // Handle summary. Show only the first few words. if (show_summary) { ustring summary = note; replace_text(summary, "\n", " "); replace_text(summary, "<BR>", " "); Parse parse(summary, false); unsigned int maximum = 5; maximum = CLAMP(maximum, 0, parse.words.size()); summary.clear(); for (unsigned int w = 0; w < maximum; w++) { summary.append(" "); summary.append(parse.words[w]); } if (!summary.empty()) summary.append(" ..."); note_buffer.append(summary); } // Append a new line. note_buffer.append("<BR>\n"); // Insert text of the references, if requested. if (show_reference_text) { for (unsigned int r = 0; r < references.size(); r++) { vector <unsigned int> simple_verses = verse_range_sequence(references[r].verse_get()); for (unsigned int sv = 0; sv < simple_verses.size(); sv++) { Reference ref(references[r]); ref.verse_set(convert_to_string(simple_verses[sv])); note_buffer.append(ref.human_readable(language)); note_buffer.append(" "); ustring text = project_retrieve_verse(project, ref); if (!text.empty()) { text = usfm_get_verse_text_only (text); } note_buffer.append(text); note_buffer.append("<BR>\n"); } } } // Get the text of the note. if (!show_summary) { note_buffer.append(note); note_buffer.append("<BR>\n"); } }
ustring script_filter(const ustring & scriptname, bool straightthrough, const ustring & inputfile, const ustring & outputfile) /* Runs the filter "scriptname". Input text in "inputfile", and the output text goes in "outputfile". If everything is okay, it returns nothing. If there were errors, it returns these. */ { // Remove any previous output. unlink(outputfile.c_str()); unlink(script_temporal_error_file().c_str()); // Handle straight through. if (straightthrough) { unix_cp(inputfile, outputfile); return ""; } // Get the filename and the type of the script. ScriptType scripttype; ustring scriptfile = script_get_path(scriptname, &scripttype, true); // If the rules file does not exist, or the script is of an unknown type, pass it straight through. if (!g_file_test(scriptfile.c_str(), G_FILE_TEST_IS_REGULAR) || (scripttype == stEnd)) { unix_cp(inputfile, outputfile); gw_warning(_("Error in script ") + scriptname); return ""; } // Encode the input usfm file. ustring encodedinputfile = script_temporal_input_file(); if (inputfile != encodedinputfile) { unix_cp(inputfile, encodedinputfile); } script_encode_usfm_file(encodedinputfile); // Run filter. ustring command; ustring error; switch (scripttype) { case stSed: { command.append(script_sed_binary()); command.append(" -f"); command.append(shell_quote_space(scriptfile)); command.append("<"); command.append(shell_quote_space(encodedinputfile)); command.append(">"); command.append(shell_quote_space(outputfile)); break; } case stTECkit: { command.append(script_teckit_txtconverter()); command.append(" -i"); command.append(shell_quote_space(encodedinputfile)); command.append(" -o"); command.append(shell_quote_space(outputfile)); command.append(" -t"); command.append(shell_quote_space(scriptfile)); command.append(" -nobom"); break; } case stFree: { // Text of the script. ustring scriptdata; { // Read script. gchar *contents; g_file_get_contents(scriptfile.c_str(), &contents, NULL, NULL); if (contents) { scriptdata = contents; g_free(contents); } else { error = _("Can't read script file"); gw_warning(error); return error; } } // Check for and insert the input filename. if (scriptdata.find(script_free_input_identifier()) == string::npos) { error = _("Can't find where to put input file"); gw_warning(error); return error; } replace_text(scriptdata, script_free_input_identifier(), shell_quote_space(encodedinputfile)); // Check for and insert the output filename. if (scriptdata.find(script_free_output_identifier()) == string::npos) { error = _("Can't find where to put output file"); gw_warning(error); return error; } replace_text(scriptdata, script_free_output_identifier(), shell_quote_space(outputfile)); // Write temporal script. g_file_set_contents(script_temporal_script_file().c_str(), scriptdata.c_str(), -1, NULL); // Assemble command to run. command.append("sh"); command.append(shell_quote_space(script_temporal_script_file())); break; } case stEnd: { break; } } // Add the error file to the command, and run it. command.append(" 2> "); command.append(script_temporal_error_file()); int result = system(command.c_str()); // This one is too unpredictable to be used with GwSpawn. // The filters are so much beyond any control that we never can be sure that // their output is in the UTF-8 encoding. // Sed would give UTF-8, but as TECkit can also give legacy encodings. // We can't know what free scripts will do, it could be anything. // So here check the UTF-8 encoding. // If UTF-8 validation fails, we copy the input straight to the output. { gchar *contents; g_file_get_contents(outputfile.c_str(), &contents, NULL, NULL); if (contents) { if (!g_utf8_validate(contents, -1, NULL)) { unix_cp(inputfile, outputfile); error = _("UTF-8 validation failure"); gw_warning(error); } g_free(contents); if (!error.empty()) return error; } } // Decode the output file. script_decode_usfm_file(outputfile); // Handle OK. if (result == 0) return ""; // Handle error. gchar *contents; g_file_get_contents(script_temporal_error_file().c_str(), &contents, NULL, NULL); if (contents) { error = contents; g_free(contents); gw_warning(error); } return error; }
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); }
void TextWidget::cut() { int start, end; get_cursor_slice(start, end); gui_window->set_clipboard_string(_label.text().substring(start, end)); replace_text(start, end, "", 0); }
void kjv_import_sword (const ustring& textfile, const ustring& database) { // Show the progress. KJV has 31102 verses. ProgressWindow progresswindow (_("Importing King James Bible"), false); progresswindow.set_iterate (0, 1, 31102); gchar * contents; g_file_get_contents(textfile.c_str(), &contents, NULL, NULL); if (!contents) return; // Create the database, put it in fast mode. unix_unlink (database.c_str()); sqlite3 *db; sqlite3_open(database.c_str(), &db); sqlite3_exec(db, "create table kjv (book integer, chapter integer, verse integer, item integer, fragment text, lemma text);", NULL, NULL, NULL); sqlite3_exec(db, "PRAGMA synchronous=OFF;", NULL, NULL, NULL); // Parse input. xmlParserInputBufferPtr inputbuffer; inputbuffer = xmlParserInputBufferCreateMem(contents, strlen (contents), XML_CHAR_ENCODING_NONE); xmlTextReaderPtr reader = xmlNewTextReader(inputbuffer, NULL); if (reader) { bool within_relevant_element = false; Reference reference (0, 0, "0"); unsigned int item_number = 0; ustring textfragment; ustring lemmata; while ((xmlTextReaderRead(reader) == 1)) { switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_ELEMENT: { xmlChar *element_name = xmlTextReaderName(reader); // Deal with a verse element. if (!xmlStrcmp(element_name, BAD_CAST "verse")) { progresswindow.iterate(); char *attribute; attribute = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "osisID"); if (attribute) { Parse parse (attribute, false, "."); if (parse.words.size() == 3) { reference.assign(books_osis_to_id (parse.words[0]), // book convert_to_int (parse.words[1]), // chapter parse.words[2]); // verse } else { gw_critical (attribute); } free(attribute); } item_number = 0; } // Deal with a w element. if (!xmlStrcmp(element_name, BAD_CAST "w")) { within_relevant_element = true; item_number++; textfragment.clear(); lemmata.clear(); char *attribute; attribute = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "lemma"); if (attribute) { lemmata = attribute; free(attribute); } } break; } case XML_READER_TYPE_TEXT: { if (within_relevant_element) { xmlChar *text = xmlTextReaderValue(reader); if (text) { textfragment = (const char *)text; xmlFree(text); textfragment = textfragment.casefold(); } } break; } case XML_READER_TYPE_END_ELEMENT: { xmlChar *element_name = xmlTextReaderName(reader); if (!xmlStrcmp(element_name, BAD_CAST "w")) { replace_text (lemmata, "strong:", ""); char *sql; sql = g_strdup_printf("insert into kjv values (%d, %d, %d, %d, '%s', '%s');", reference.book_get(), reference.chapter_get(), convert_to_int (reference.verse_get()), item_number, double_apostrophy (textfragment).c_str(), lemmata.c_str()); sqlite3_exec(db, sql, NULL, NULL, NULL); g_free(sql); within_relevant_element = false; } break; } } } } if (reader) xmlFreeTextReader(reader); if (inputbuffer) xmlFreeParserInputBuffer(inputbuffer); // Close database. sqlite3_close(db); // Free xml data. g_free(contents); }
bool TextWidget::on_key_event(const KeyEvent *event) { if (!_text_interaction_on) return false; if (_on_key_event(this, event)) { // user ate this event return true; } if (event->action == KeyActionUp) return false; int start, end; get_cursor_slice(start, end); switch (event->virt_key) { case VirtKeyLeft: if (key_mod_ctrl(event->modifiers) && key_mod_shift(event->modifiers)) { int new_end = backward_word(); set_selection(_cursor_start, new_end); } else if (key_mod_ctrl(event->modifiers)) { int new_start = backward_word(); set_selection(new_start, new_start); } else if (key_mod_shift(event->modifiers)) { set_selection(_cursor_start, _cursor_end - 1); } else { if (start == end) { set_selection(start - 1, start - 1); } else { set_selection(start, start); } } return true; case VirtKeyRight: if (key_mod_ctrl(event->modifiers) && key_mod_shift(event->modifiers)) { int new_end = forward_word(); set_selection(_cursor_start, new_end); } else if (key_mod_ctrl(event->modifiers)) { int new_start = forward_word(); set_selection(new_start, new_start); } else if (key_mod_shift(event->modifiers)) { set_selection(_cursor_start, _cursor_end + 1); } else { if (start == end) { set_selection(start + 1, end + 1); } else { set_selection(end, end); } } return true; case VirtKeyBackspace: if (start == end) { if (key_mod_ctrl(event->modifiers)) { int new_start = backward_word(); replace_text(new_start, start, "", 0); } else { replace_text(start - 1, end, "", 0); } } else { replace_text(start, end, "", 0); } return true; case VirtKeyDelete: if (start == end) { if (key_mod_ctrl(event->modifiers)) { int new_start = forward_word(); replace_text(start, new_start, "", 0); } else { replace_text(start, end + 1, "", 0); } } else { replace_text(start, end, "", 0); } return true; case VirtKeyHome: if (key_mod_shift(event->modifiers)) { set_selection(_cursor_start, 0); } else { set_selection(0, 0); } return true; case VirtKeyEnd: if (key_mod_shift(event->modifiers)) { set_selection(_cursor_start, _label.text().length()); } else { set_selection(_label.text().length(), _label.text().length()); } return true; case VirtKeyA: if (key_mod_only_ctrl(event->modifiers)) { select_all(); return true; } case VirtKeyX: if (key_mod_only_ctrl(event->modifiers)) { cut(); return true; } case VirtKeyC: if (key_mod_only_ctrl(event->modifiers)) { copy(); return true; } case VirtKeyV: if (key_mod_only_ctrl(event->modifiers)) { paste(); return true; } default: // do nothing return true; } }
void OpenDocument::format_general(vector <ustring>& lines) // General formatter for USFM lines given. { // Go through all the lines. odttextparagraph = NULL; for (unsigned int ln = 0; ln < lines.size(); ln++) { ustring line = lines[ln]; // Take any elastics out, put the \b marker instead. replace_text(line, ELASTIC_MARKER, "b"); // Change certain characters to xml entities. xml_handle_entities(line, NULL); // Deal with footnotes. odtfootnote->transform(line); // Deal with endnotes. odtendnote->transform(line); // Deal with crossreferences. odtxref->transform(line); // Deal with inline text. usfm_handle_inline_text(line, usfm_inline_markers, NULL, imOpenDocument, NULL); // Signal new line. if (odttextparagraph) odttextparagraph->newline(); // Get the style belonging to the marker. ustring marker = usfm_extract_marker(line); if (usfm->is_identifier(marker)) { // Handle some identifiers. IdentifierType identifiertype = usfm->identifier_get_subtype(marker); // New book. if (identifiertype == itBook) { if (odttextparagraph) delete odttextparagraph; odttextparagraph = new OdtTextParagraph(&odtlines, marker); } } else if (usfm->is_verse_number(marker)) { // Because of dealing with portions to include/exclude, handle verse first. // Get verse number. Handle combined verses too, e.g. 10-12b, etc. size_t position = line.find(" "); position = CLAMP(position, 0, line.length()); ustring versenumber = line.substr(0, position); position++; line.erase(0, position); // There was a bug that the chapter number was missing from a book, // and that results in text being inserted without the opening xml code. // Solution: If no paragraph has been opened, open a default one. if (odttextparagraph == NULL) odttextparagraph = new OdtTextParagraph(&odtlines, ""); // Insert a bookmark at the verse. // This will become an anchor for the Bibledit Resource Viewer, // once OpenOffice saves the document to a HTML Document. // Example bookmark: <text:bookmark text:name="Malachi_1_1"/> ustring bookmark = resource_viewer_produce_anchor(anchor_book, anchor_chapter, convert_to_int(number_in_string(versenumber))); bookmark.insert(0, "<text:bookmark text:name=\""); bookmark.append("\"/>"); odttextparagraph->plaintext(bookmark); // When the usfm is a verse number, then the number is put in the // format specified by the stylesheet, but the remaining part of the // line inherits the formatting from the paragraph it is in. odttextparagraph->spannedtext(versenumber, marker); odttextparagraph->plaintext(line); } else if (usfm->is_starting_paragraph(marker)) { if (odttextparagraph) delete odttextparagraph; odttextparagraph = new OdtTextParagraph(&odtlines, marker); if (!line.empty()) odttextparagraph->plaintext(line); } else if (usfm->is_inline_text(marker)) { // Inline text, has been dealt with before (therefore should never occur here). if (odttextparagraph) odttextparagraph->spannedtext(line, marker); } else if (usfm->is_chapter_number(marker)) { // Close possible open paragraph. if (odttextparagraph) delete odttextparagraph; // Signal new chapter to footnotes object. odtfootnote->new_chapter(); // Store chapter for the anchors. anchor_chapter = convert_to_int(number_in_string(line)); // Insert or prepare chapter text. odttextparagraph = new OdtTextParagraph(&odtlines, marker); odttextparagraph->plaintext(line); } else if (usfm->is_peripheral(marker)) { } else if (usfm->is_picture(marker)) { } else if (usfm->is_pagebreak(marker)) { if (odttextparagraph) delete odttextparagraph; odttextparagraph = new OdtTextParagraph(&odtlines, marker); } else { // Fallback for unknown marker or no marker. if (!odttextparagraph) odttextparagraph = new OdtTextParagraph(&odtlines, ""); odttextparagraph->plaintext(line); // Make a note of this marker, that it was not formatted. unformatted_markers.insert (marker); } } // Close possible last paragraph. if (odttextparagraph) delete odttextparagraph; }
vector <ustring> mechon_mamre_extract_contents (const ustring& file, unsigned int chapter) { // Usfm data. vector <ustring> lines; // Convert chapter number to USFM code. lines.push_back("\\c " + convert_to_string(chapter)); lines.push_back("\\p"); // Read the text of the .htm file, and select only the .htm lines that // contain the actual text. vector < ustring > htmlines; { ReadText rt (file, true, false); // Find lower boundary: the relevant parts start with a verse number. unsigned int lower_boundary = 0; for (unsigned int i = 0; i < rt.lines.size(); i++) { if (rt.lines[i].find("A NAME=") != string::npos) { lower_boundary = i; break; } } // Find higher boundary: the relevant part ends with a verse number // that is one past the last verse. unsigned int upper_boundary = 0; for (unsigned int i = rt.lines.size() - 1; i > 0; i--) { if (rt.lines[i].find("A NAME=") != string::npos) { upper_boundary = i; upper_boundary++; break; } } // Store the relevant html lines that contain the verses. for (unsigned int i = lower_boundary; i <= upper_boundary; i++) { htmlines.push_back(rt.lines[i]); } } // Go through the relevant text and extract the verses. ustring verse; for (unsigned int ln = 0; ln < htmlines.size(); ln++) { ustring s = number_in_string(htmlines[ln]); if (!s.empty()) { verse = "\\v " + s; } else { // A text line could be looking so (Psalms 1:1): // <P><B>א</B> אַ֥שְֽׁרֵי הָאִ֗ישׁ אֲשֶׁ֤ר ׀ לֹ֥א הָלַךְ֮ בַּֽעֲצַ֪ת רְשָׁ֫עִ֥ים<BR>וּבְדֶ֣רֶךְ חַ֭טָּאִים לֹ֥א עָמָ֑ד וּבְמוֹשַׁ֥ב לֵ֝צִ֗ים לֹ֣א יָשָֽׁב׃<BR> ustring line = htmlines[ln]; // Convert <BR>, </P>, etc. replace_text(line, "<BR>", "\n\\nb\n"); replace_text(line, "</P>", "\n\\p\n"); replace_text(line, "<BIG>", ""); replace_text(line, "</BIG>", ""); replace_text(line, "{פ}", ""); replace_text(line, "{ס}", ""); size_t position = line.find_last_of(">"); line.erase(0, ++position); line = trim(line); lines.push_back(verse + " " + line); } } // Return the data. return lines; }