void notes_get_references_from_editor(GtkTextBuffer * textbuffer, vector < Reference > &references, vector < ustring > &messages) /* Gets all references from the notes editor. Normalizes them. Produces messages on trouble. Handles notes that span more than one chapter. */ { // Get all lines from the textbuffer. vector < ustring > lines; textbuffer_get_lines(textbuffer, lines); // When discovering a reference from a user's entry, use previous values, // so that it becomes quicker for a user to enter new references. // If Leviticus 10:11 is already there, and the user wishes to add verse // 12 also, he just enters 12 on a line, and that' it. Reference previousreference; for (unsigned int i = 0; i < lines.size(); i++) { if (!lines[i].empty()) { // Normalize reference. Reference reference; if (reference_discover(previousreference, lines[i], reference)) { ustring ch1, vs1, ch2, vs2; if (chapter_span_discover(lines[i], ch1, vs1, ch2, vs2)) { // We cross the chapter boundaries. // Store as two or more references, // the first one going up to the end of the chapter, // and the second one starting at the next chapter verse 1, // and any chapter in-between. extern Settings *settings; ProjectConfiguration *projectconfig = settings->projectconfig(settings->genconfig.project_get()); Reference ref(reference.book_get(), convert_to_int(ch1), vs1); ustring lastverse = versification_get_last_verse(projectconfig->versification_get(), reference.book_get(), convert_to_int(ch1)); ref.verse_append("-" + lastverse); references.push_back(ref); for (unsigned int ch = convert_to_int(ch1) + 1; ch < convert_to_int(ch2); ch++) { Reference ref(reference.book_get(), ch, "1"); ustring lastverse = versification_get_last_verse(projectconfig->versification_get(), reference.book_get(), ch); ref.verse_append("-" + lastverse); references.push_back(ref); } ref.chapter_set(convert_to_int(ch2)); ref.verse_set("1-" + vs2); references.push_back(ref); // Store values to discover next reference. previousreference.book_set(reference.book_get()); previousreference.chapter_set(convert_to_int(ch2)); previousreference.verse_set(vs2); } else { // We've a normal reference. // Store reference. references.push_back(reference); // Store values to discover next reference. previousreference.assign(reference); } } else { messages.push_back(_("Reference ") + lines[i] + _(" is not valid and has been removed.")); } } } }
Reference WindowCheckKeyterms::get_reference (const ustring& text) // Generates a reference out of the text. { Reference ref; ustring book, chapter, verse = ref.verse_get(); decode_reference(text, book, chapter, verse); ref.book_set(books_english_to_id (book)); ref.chapter_set(convert_to_int (chapter)); ref.verse_set(verse); return ref; }
void WindowCheckKeyterms::html_write_keyterms (HtmlWriter2& htmlwriter, unsigned int keyword_id) { // Get data about the project. extern Settings *settings; ustring project = settings->genconfig.project_get(); ProjectConfiguration *projectconfig = settings->projectconfig(project); ustring versification = projectconfig->versification_get(); // Add action links. htmlwriter.paragraph_open (); htmlwriter.hyperlink_add ("index", "[Index]"); htmlwriter.text_add (" "); htmlwriter.hyperlink_add ("send", _("[Send to references window]")); htmlwriter.paragraph_close (); // Add the keyterm itself. ustring keyterm; keyterms_get_term(keyword_id, keyterm); htmlwriter.heading_open (3); htmlwriter.text_add (keyterm); htmlwriter.heading_close(); // Retrieve the renderings. vector <ustring> renderings; vector <bool> wholewords; vector <bool> casesensitives; get_renderings(renderings, wholewords, casesensitives); // Get the data for the keyword identifier. ustring dummy; ustring information; keyterms_get_data(keyword_id, dummy, information, references); // Divide the information into lines. ParseLine parseline (information); // Write the information. for (unsigned int i = 0; i < parseline.lines.size(); i++) { information = parseline.lines[i]; htmlwriter.paragraph_open (); size_t pos = information.find (keyterms_reference_start_markup ()); while (pos != string::npos) { htmlwriter.text_add (information.substr (0, pos)); information.erase (0, pos + keyterms_reference_start_markup ().length()); pos = information.find (keyterms_reference_end_markup ()); if (pos != string::npos) { // Extract the reference. htmlwriter.paragraph_close (); ustring original_reference_text = information.substr (0, pos); Reference reference = get_reference (original_reference_text); // Remap the reference. { Mapping mapping(versification, reference.book_get()); vector <int> chapters; vector <int> verses; mapping.original_to_me(reference.chapter_get(), reference.verse_get(), chapters, verses); if (!chapters.empty()) { reference.chapter_set(chapters[0]); reference.verse_set(convert_to_string (verses[0])); } } ustring remapped_reference_text = reference.human_readable (""); ustring displayed_reference_text (remapped_reference_text); if (remapped_reference_text != original_reference_text) { displayed_reference_text.append (" ("); displayed_reference_text.append (original_reference_text); displayed_reference_text.append (")"); } // Add the reference with hyperlink. htmlwriter.hyperlink_add ("goto " + remapped_reference_text, remapped_reference_text); information.erase (0, pos + keyterms_reference_end_markup ().length()); // Add the reference's text. ustring verse = project_retrieve_verse(project, reference); if (verse.empty()) { verse.append(_("<empty>")); } else { CategorizeLine cl(verse); cl.remove_verse_number(reference.verse_get()); verse = cl.verse; } htmlwriter.text_add (" "); // Add the verse plus markup for approved text. vector <size_t> startpositions; vector <size_t> lengths; size_t processposition = 0; if (find_renderings (verse, renderings, wholewords, casesensitives, &startpositions, &lengths)) { quick_sort (startpositions, lengths, 0, startpositions.size()); // Overlapping items need to be combined to avoid crashes. xml_combine_overlaps (startpositions, lengths); for (unsigned int i = 0; i < startpositions.size(); i++) { htmlwriter.text_add (verse.substr (0, startpositions[i] - processposition)); htmlwriter.bold_open(); htmlwriter.text_add (verse.substr (startpositions[i] - processposition, lengths[i])); htmlwriter.bold_close(); verse.erase (0, startpositions[i] - processposition + lengths[i]); processposition = startpositions[i] + lengths[i]; } // Add whatever is left over of the verse. This could be the full verse in case it wasn't processed. htmlwriter.text_add (verse); } else { htmlwriter.highlight_open(); htmlwriter.text_add (verse); htmlwriter.highlight_close(); } // Proceed to next. htmlwriter.paragraph_open (); pos = information.find (keyterms_reference_start_markup ()); } } htmlwriter.text_add (information); htmlwriter.paragraph_close (); } }
void OTQuotations::read() { // Get contents of the data file. Bail out if not there. ustring xmlfilename = gw_build_filename(Directories->get_package_data(), "ot-quotations-in-nt.xml"); if (!g_file_test(xmlfilename.c_str(), G_FILE_TEST_IS_REGULAR)) return; gchar *contents; g_file_get_contents(xmlfilename.c_str(), &contents, NULL, NULL); /* Read the xml data. Example: <set> <nt book="Matthew" chapter="1" verse="23"/> <ot book="Isaiah" chapter="8" verse="8"/> <ot book="Isaiah" chapter="8" verse="10"/> <lxx>1</lxx> </set> */ xmlParserInputBufferPtr inputbuffer; inputbuffer = xmlParserInputBufferCreateMem(contents, strlen(contents), XML_CHAR_ENCODING_NONE); xmlTextReaderPtr reader = xmlNewTextReader(inputbuffer, NULL); if (reader) { char *opening_element = NULL; OTQuotation quotation(0); while ((xmlTextReaderRead(reader) == 1)) { switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_ELEMENT: { opening_element = (char *)xmlTextReaderName(reader); if (!strcmp(opening_element, "set")) { quotation.reference.clear(); quotation.referents.clear(); quotation.lxx = false; free(opening_element); opening_element = NULL; // not used next loop iteration } else if (!strcmp(opening_element, "nt") || !strcmp(opening_element, "ot")) { Reference ref; char *attribute; attribute = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "book"); if (attribute) { ref.book_set(books_english_to_id(attribute)); free(attribute); } attribute = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "chapter"); if (attribute) { ref.chapter_set(convert_to_int(attribute)); free(attribute); } attribute = (char *)xmlTextReaderGetAttribute(reader, BAD_CAST "verse"); if (attribute) { ref.verse_set(attribute); free(attribute); } if (!strcmp(opening_element, "nt")) { quotation.reference.assign(ref); } if (!strcmp(opening_element, "ot")) { quotation.referents.push_back(ref); } // cannot free(opening_element) because it will be used next loop iter in following switch case } break; } case XML_READER_TYPE_TEXT: { char *text = (char *)xmlTextReaderValue(reader); if (opening_element && text) { if (!strcmp(opening_element, "lxx")) { quotation.lxx = convert_to_bool(text); } free(text); free(opening_element); opening_element = NULL; } break; } case XML_READER_TYPE_END_ELEMENT: { char *closing_element = (char *)xmlTextReaderName(reader); if (!strcmp(closing_element, "set")) { quotations_nt_order.push_back(quotation); } free(closing_element); break; } } } } // Free memory. if (reader) xmlFreeTextReader(reader); if (inputbuffer) xmlFreeParserInputBuffer(inputbuffer); if (contents) g_free(contents); }