Пример #1
0
void notes_handle_vcs_feedback (const ustring& directory, const ustring& feedback)
// This handles the feedback that comes from the version control system.
{
    if (directory == notes_shared_storage_folder ()) {

        unsigned int note_id = 0;

        // The following feedback indicates that somebody created a new note:
        // create mode 100644 27185458
        if (feedback.find ("create mode") != string::npos) {
            ustring s (feedback);
            s.erase (12);
            Parse parse (s);
            if (parse.words.size () == 2) {
                note_id = convert_to_int (parse.words[1]);
            }
        }

        // The following feedback indicates that somebody modified a note:
        // #	modified:   27185458
        if (feedback.find ("modified:") != string::npos) {
            ustring s (feedback);
            s.erase (12);
            note_id = convert_to_int (number_in_string (feedback));
        }

        // The following feedback indicates that somebody deleted a note:
        // #	deleted:    46473236
        if (feedback.find ("deleted:") != string::npos) {
            ustring s (feedback);
            s.erase (11);
            note_id = convert_to_int (number_in_string (feedback));
        }

        // See the following:
        // 95935882 |    9 +++++++++
        // It means that this note was edited.
        if (feedback.find (" |  ") != string::npos) {
            note_id = convert_to_int (number_in_string (feedback));
        }

        if (note_id != 0) {
            gw_message (_("Change detected for note ") + convert_to_string (note_id));
            // Update the index.
            sqlite3 *db;
            sqlite3_open(notes_index_filename ().c_str(), &db);
            sqlite3_busy_timeout(db, 1000);
            notes_store_index_entry (db, note_id);
            sqlite3_close(db);
        }
    }
}
Пример #2
0
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;
}
Пример #3
0
CategorizeChapterVerse::CategorizeChapterVerse(const vector < ustring > &lines)
// Categorizes the lines by adding chapter and verse information to it.
// It expects each \c and \v to start a new line, i.e. the lines are "clean".
// Gives one line per verse.
{
  // Variables.
  unsigned int chapternumber = 0;
  ustring versenumber = "0";
  ustring text;
  unsigned int previous_chapter = 0;
  ustring previous_verse = "0";
  // Go through all the lines.
  for (unsigned int i = 0; i < lines.size(); i++) {
    // Extract the marker, and deal with it.
    ustring ln = lines[i];
    ustring marker = usfm_extract_marker(ln);
    // Chapter. 
    if (marker == "c") {
      ustring number_in_line = number_in_string(ln);
      // Only accept the number if it is well-formed.
      if ((ln.substr(0, number_in_line.length()) == number_in_line) && (!number_in_line.empty())) {
        chapternumber = convert_to_int(number_in_line);
        if (i == 0)
          previous_chapter = chapternumber;     // For one-chapter texts
        versenumber = "0";
      }
    }
    // Verse
    if (marker == "v") {
      versenumber = ln;
      // Make it robust, even handling cases like:
      // - \v 1-2"Moi - No space after verse number.
      size_t spaceposition = versenumber.find_first_not_of("0123456789,-ab");
      if (spaceposition != string::npos) {
        versenumber = versenumber.substr(0, spaceposition);
      }
      // Handle case that the usfm file does not contain the \c 1.
      if ((versenumber != "0") && (chapternumber == 0)) {
        chapternumber = 1;
      }
    }
    // Store data.
    if ((chapternumber != previous_chapter) || (versenumber != previous_verse)) {
      store(previous_chapter, previous_verse, text);
      text.clear();
      previous_chapter = chapternumber;
      previous_verse = versenumber;
    }
    // Save text.
    if (!text.empty())
      text.append("\n");
    text.append(lines[i]);
  }
  if (!text.empty())
    store(chapternumber, versenumber, text);
}
Пример #4
0
void NotesTransferDialog::clean_note(ustring & note)
// "Cleans" the note: removes unnecessary stuff.
{
  ustring working_copy(note);
  ustring marker = usfm_extract_marker(working_copy);
  if (marker == "v") {
    usfm_extract_marker(note);
    note = trim(note);
    ustring verse = number_in_string(note);
    note.erase(0, verse.length());
    note = trim(note);
  }
}
Пример #5
0
void GotoReferenceDialog::on_move_chapter()
{
  extern Settings *settings;
  // Chapter number changed, therefore update the verse numbers.
  ustring chapter = listview_get_active_string(treeview_chapter);
  // Something weird in Gtk: If the listview was not in view, it gives no results.
  // Deal with that here.
  if (chapter.empty())
    return;
  // Get the verses as they are in the chapter.
  unsigned int bookid = books_name_to_id(language, listview_get_active_string(treeview_book));
  vector < ustring > verses;
  verses = project_get_verses(settings->genconfig.project_get(), bookid, convert_to_int(chapter));
  // The verses may contain sequences and ranges, but fill them up with the 
  // verses contained in those. E.g.: 10-12 also contains 11.
  vector < ustring > verses2;
  set < ustring > verses2_set;
  for (unsigned int i = 0; i < verses.size(); i++) {
    verses2.push_back(verses[i]);
    if (number_in_string(verses[i]) != verses[i]) {
      vector < unsigned int >int_verses = verse_range_sequence(verses[i]);
      for (unsigned int i2 = 0; i2 < int_verses.size(); i2++) {
        ustring verse2 = convert_to_string(int_verses[i2]);
        // No double verses will be listed.
        if (verses2_set.find(verse2) == verses2_set.end()) {
          verses2.push_back(verse2);
        }
        verses2_set.insert(verse2);
      }
    }
  }
  listview_set_strings(treeview_verse, store_verse, verses2);
  if (oldbook == bookid)
    if (oldchapter == convert_to_int(chapter))
      listview_focus_string(treeview_verse, oldverse);
}
Пример #6
0
void CheckValidateUsfm::check(const ustring & text)
// Do the actual check of one verse.
{
  // Extract the marker, and deal with it.
  ustring utext = trim(text);
  if (utext.empty())
    return;
  ustring line = utext;
  ustring marker = usfm_extract_marker_within_line(line);
  if (marker.empty()) {
    // No marker found.
    message(_("Line without USFM"));
  }
  while (!marker.empty()) {

    if (marker == "id") {
      // Is the line long enough?
      if (line.length() < 3) {
        message(_("ID line is too short: ") + line);
      } else {
        ustring id = line.substr(0, 3);
        unsigned int myid = books_paratext_to_id(id);
        if (myid == 0)
          message(_("Unknown id ") + id);
        if (id != upperCase(id))
          message(_("Non-uppercase id code"));
      }
    } else if (marker == "c") {
    } else if (marker == "v") {
      // Is there a space after the verse number?
      // Check it by extracting the text will the first space, and see if any unusual characters are in it.
      // It should cover things like \v 10a-11b or \v 10,11
      size_t position = line.find(" ");
      position = CLAMP(position, 0, line.length());
      ustring verse_number = line.substr (0, position);
      for (unsigned int i = 0; i < verse_number.length(); i++) {
        ustring character = verse_number.substr (i, 1);
        if (number_in_string (character) != character) {
          if ((character != "a") || (character != "b") || (character != "-") || (character != ",")) {
            message (_("Unusual character in verse number ") + verse_number);
            break;
          }
        }
      }
    } else if (marker == "add") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "bdit") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "bd") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "bk") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "b") {
    } else if (marker == "ca") {
    } else if (marker == "cd") {
    } else if (marker == "cls") {
    } else if (marker == "cl") {
    } else if (marker == "conc") {
    } else if (marker == "cov") {
    } else if (marker == "cp") {
    } else if (marker == "dc") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "d") {
    } else if (marker == "em") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "fdc") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fe") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "fig") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "fk") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fl") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fm") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "fp") {
    } else if (marker == "fqa") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fq") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fr") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "ft") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "fv") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "f") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "fb") { 
      // todo rogue fix - this check needs to be based on stylesheet, not hard coded.
      // A task was opened for this to be done.
      check_on_endmarker(line, marker, false);
    } else if (marker == "fx") { 
      // todo rogue fix - this check needs to be based on stylesheet, not hard coded.
      // A task was opened for this to be done.
      check_on_endmarker(line, marker, false);
    } else if (marker == "glo") {
    } else if (marker == "h1") {
    } else if (marker == "h2") {
    } else if (marker == "h3") {
    } else if (marker == "h") {
    } else if (marker == "ib") {
    } else if (marker == "ide") {
    } else if (marker == "idx") {
    } else if (marker == "ie") {
    } else if (marker == "iex") {
    } else if (marker == "imi") {
    } else if (marker == "imq") {
    } else if (marker == "imt1") {
    } else if (marker == "imt2") {
    } else if (marker == "imt3") {
    } else if (marker == "imt4") {
    } else if (marker == "imte") {
    } else if (marker == "imt") {
    } else if (marker == "im") {
    } else if (marker == "intro") {
    } else if (marker == "io1") {
    } else if (marker == "io2") {
    } else if (marker == "io3") {
    } else if (marker == "io4") {
    } else if (marker == "ior") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "iot") {
    } else if (marker == "io") {
    } else if (marker == "ipi") {
    } else if (marker == "ipq") {
    } else if (marker == "ipr") {
    } else if (marker == "ip") {
    } else if (marker == "iq1") {
    } else if (marker == "iq2") {
    } else if (marker == "iq3") {
    } else if (marker == "iq") {
    } else if (marker == "is1") {
    } else if (marker == "is2") {
    } else if (marker == "is") {
    } else if (marker == "it") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "k1") {
    } else if (marker == "k2") {
    } else if (marker == "k") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "li1") {
    } else if (marker == "li2") {
    } else if (marker == "li3") {
    } else if (marker == "li4") {
    } else if (marker == "lit") {
    } else if (marker == "li") {
    } else if (marker == "maps") {
    } else if (marker == "mi") {
    } else if (marker == "mr") {
    } else if (marker == "ms1") {
    } else if (marker == "ms2") {
    } else if (marker == "ms") {
    } else if (marker == "mt1") {
    } else if (marker == "mt2") {
    } else if (marker == "mt3") {
    } else if (marker == "mt4") {
    } else if (marker == "mte1") {
    } else if (marker == "mte2") {
    } else if (marker == "mte") {
    } else if (marker == "mt") {
    } else if (marker == "m") {
    } else if (marker == "nb") {
    } else if (marker == "nd") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "ndx") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "no") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "ord") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "p1") {
    } else if (marker == "p2") {
    } else if (marker == "pb") {
    } else if (marker == "pc") {
    } else if (marker == "pi1") {
    } else if (marker == "pi2") {
    } else if (marker == "pi3") {
    } else if (marker == "pi") {
    } else if (marker == "pmc") {
    } else if (marker == "pmo") {
    } else if (marker == "pmr") {
    } else if (marker == "pm") {
    } else if (marker == "pn") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "pref") {
    } else if (marker == "pro") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "pubinfo") {
    } else if (marker == "pub") {
    } else if (marker == "p") {
    } else if (marker == "q1") {
    } else if (marker == "q2") {
    } else if (marker == "q3") {
    } else if (marker == "qac") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "qa") {
    } else if (marker == "qc") {
    } else if (marker == "qm1") {
    } else if (marker == "qm2") {
    } else if (marker == "qm3") {
    } else if (marker == "qm") {
    } else if (marker == "qr") {
    } else if (marker == "qs") {
    } else if (marker == "qt") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "q") {
    } else if (marker == "rem") {
    } else if (marker == "restore") {
    } else if (marker == "r") {
    } else if (marker == "rq") {
    } else if (marker == "s1") {
    } else if (marker == "s2") {
    } else if (marker == "s3") {
    } else if (marker == "s4") {
    } else if (marker == "sc") {
      check_on_endmarker(line, marker, false);
      deprecated_marker(marker);
    } else if (marker == "sig") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "sls") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "spine") {
    } else if (marker == "sp") {
    } else if (marker == "sr") {
    } else if (marker == "s") {
    } else if (marker == "tc1") {
    } else if (marker == "tc2") {
    } else if (marker == "tc3") {
    } else if (marker == "tc4") {
    } else if (marker == "tcr1") {
    } else if (marker == "tcr2") {
    } else if (marker == "tcr3") {
    } else if (marker == "tcr4") {
    } else if (marker == "th1") {
    } else if (marker == "th2") {
    } else if (marker == "th3") {
    } else if (marker == "th4") {
    } else if (marker == "thr1") {
    } else if (marker == "thr2") {
    } else if (marker == "thr3") {
    } else if (marker == "thr4") {
    } else if (marker == "tl") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "toc1") {
    } else if (marker == "toc2") {
    } else if (marker == "toc3") {
    } else if (marker == "toc") {
    } else if (marker == "tr") {
    } else if (marker == "va") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "vp") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "wg") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "wh") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "wj") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "w") {
      check_on_endmarker(line, marker, false);
    } else if (marker == "xdc") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "xk") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "xo") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "xq") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "xt") {
      check_on_endmarker(line, marker, true);
    } else if (marker == "x") {
      check_on_endmarker(line, marker, false);
    } else if (marker.find("*") != string::npos) {
      message(_("Unmatched end marker ") + marker);
    } else {
      message(_("Unknown USFM ") + marker);
    }

    // Optionally check whether this marker is in the stylesheet.
    if (mychecksheet) {
      if (styles.find(marker) == styles.end()) {
        message(_("Marker ") + marker + _(" not in stylesheet"));
      }
    }
    // Extract any next marker in this line.    
    marker = usfm_extract_marker_within_line(line);
  }

  // Deal with accidentally entered forward slashes instead of backslashes.
  line = utext;
  marker = usfm_extract_marker_with_forwardslash(line);
  while (!marker.empty()) {
    ustring originalmarker(marker);
    size_t pos = marker.find("*");
    if (pos != string::npos) {
      marker.erase(pos, 1);
    }
    if ((marker == "id")
        || (marker == "c")
        || (marker == "v")
        || (marker == "add")
        || (marker == "bdit")
        || (marker == "bd")
        || (marker == "bk")
        || (marker == "b")
        || (marker == "ca")
        || (marker == "cd")
        || (marker == "cls")
        || (marker == "cl")
        || (marker == "conc")
        || (marker == "cov")
        || (marker == "cp")
        || (marker == "dc")
        || (marker == "d")
        || (marker == "em")
        || (marker == "fdc")
        || (marker == "fe")
        || (marker == "fig")
        || (marker == "fk")
        || (marker == "fl")
        || (marker == "fm")
        || (marker == "fp")
        || (marker == "fqa")
        || (marker == "fq")
        || (marker == "fr")
        || (marker == "ft")
        || (marker == "fv")
        || (marker == "f")
        || (marker == "glo")
        || (marker == "h1")
        || (marker == "h2")
        || (marker == "h3")
        || (marker == "h")
        || (marker == "ib")
        || (marker == "ide")
        || (marker == "idx")
        || (marker == "ie")
        || (marker == "iex")
        || (marker == "imi")
        || (marker == "imq")
        || (marker == "imt1")
        || (marker == "imt2")
        || (marker == "imt3")
        || (marker == "imt4")
        || (marker == "imte")
        || (marker == "imt")
        || (marker == "im")
        || (marker == "intro")
        || (marker == "io1")
        || (marker == "io2")
        || (marker == "io3")
        || (marker == "io4")
        || (marker == "ior")
        || (marker == "iot")
        || (marker == "io")
        || (marker == "ipi")
        || (marker == "ipq")
        || (marker == "ipr")
        || (marker == "ip")
        || (marker == "iq1")
        || (marker == "iq2")
        || (marker == "iq3")
        || (marker == "iq")
        || (marker == "is1")
        || (marker == "is2")
        || (marker == "is")
        || (marker == "it")
        || (marker == "k1")
        || (marker == "k2")
        || (marker == "k")
        || (marker == "li1")
        || (marker == "li2")
        || (marker == "li3")
        || (marker == "li4")
        || (marker == "lit")
        || (marker == "li")
        || (marker == "maps")
        || (marker == "mi")
        || (marker == "mr")
        || (marker == "ms1")
        || (marker == "ms2")
        || (marker == "ms")
        || (marker == "mt1")
        || (marker == "mt2")
        || (marker == "mt3")
        || (marker == "mt4")
        || (marker == "mte1")
        || (marker == "mte2")
        || (marker == "mte")
        || (marker == "mt")
        || (marker == "m")
        || (marker == "nb")
        || (marker == "nd")
        || (marker == "ndx")
        || (marker == "no")
        || (marker == "ord")
        || (marker == "p1")
        || (marker == "p2")
        || (marker == "pb")
        || (marker == "pc")
        || (marker == "pi1")
        || (marker == "pi2")
        || (marker == "pi3")
        || (marker == "pi")
        || (marker == "pmc")
        || (marker == "pmo")
        || (marker == "pmr")
        || (marker == "pm")
        || (marker == "pn")
        || (marker == "pref")
        || (marker == "pro")
        || (marker == "pubinfo")
        || (marker == "pub")
        || (marker == "p")
        || (marker == "q1")
        || (marker == "q2")
        || (marker == "q3")
        || (marker == "qac")
        || (marker == "qa")
        || (marker == "qc")
        || (marker == "qm1")
        || (marker == "qm2")
        || (marker == "qm3")
        || (marker == "qm")
        || (marker == "qr")
        || (marker == "qs")
        || (marker == "qt")
        || (marker == "q")
        || (marker == "rem")
        || (marker == "restore")
        || (marker == "r")
        || (marker == "rq")
        || (marker == "s1")
        || (marker == "s2")
        || (marker == "s3")
        || (marker == "s4")
        || (marker == "sc")
        || (marker == "sig")
        || (marker == "sls")
        || (marker == "spine")
        || (marker == "sp")
        || (marker == "sr")
        || (marker == "s")
        || (marker == "tc1")
        || (marker == "tc2")
        || (marker == "tc3")
        || (marker == "tc4")
        || (marker == "tcr1")
        || (marker == "tcr2")
        || (marker == "tcr3")
        || (marker == "tcr4")
        || (marker == "th1")
        || (marker == "th2")
        || (marker == "th3")
        || (marker == "th4")
        || (marker == "thr1")
        || (marker == "thr2")
        || (marker == "thr3")
        || (marker == "thr4")
        || (marker == "tl")
        || (marker == "toc1")
        || (marker == "toc2")
        || (marker == "toc3")
        || (marker == "toc")
        || (marker == "tr")
        || (marker == "va")
        || (marker == "vp")
        || (marker == "wg")
        || (marker == "wh")
        || (marker == "wj")
        || (marker == "w")
        || (marker == "xdc")
        || (marker == "xk")
        || (marker == "xo")
        || (marker == "xq")
        || (marker == "xt")
        || (marker == "x")
        ) {
      message(_("Normal slash for /") + originalmarker);
    }
    // Extract any next marker in this line.    
    marker = usfm_extract_marker_with_forwardslash(line);
  }

  // Check for widow backslashes.
  line = utext + " ";
  if ((line.find("\\ ") != string::npos) || (line == "\\")) {
    message(_("Widow backslash"));
  }
}
Пример #7
0
void PrintProject2::print()
// Runs the project through xetex and shows it in a pdf viewer.
{
  // Scripture related data.
  // Possible exclusion of books.
  if (portionproject.empty())
    portionproject = myproject->name;
  scriptureportions = new ScripturePortions(portionproject);
  if (scriptureportions->books.empty()) {
    gtkw_dialog_info(NULL, _("There were no books to print\nSelect some books and try again"));
    return;
  }

  // Create the XeTeX object.
  XeTeX xetex (0);

  // Usfm style object.
  Usfm usfm (stylesheet_get_actual ());

  // Collect usfm code for all the books.
  for (unsigned int i = 0; i < scriptureportions->books.size(); i++) {

    // Book id.
    unsigned int book_id = books_english_to_id(scriptureportions->books[i]);

    // Ranges to include.
    WithinReferencesRange inrange;
    {
      vector <unsigned int> chapters_from, chapters_to;
      vector <ustring> verses_from, verses_to;
      select_portion_get_values(portionproject, book_id, scriptureportions->portions[i], chapters_from, verses_from, chapters_to, verses_to);
      inrange.add_portion(book_id, chapters_from, verses_from, chapters_to, verses_to);
    }
    inrange.set_book (book_id);
    inrange.set_chapter (0);
    inrange.set_verse ("0");

    // Open the book.
    vector <ustring> full_book_lines;
    for (unsigned int i2 = 0; i2 < myproject->data.size(); i2++) {
      if (myproject->data[i2].number == book_id) {
        full_book_lines = myproject->data[i2].get_data();
      }
    }

    // Take only those portions the user wishes to print.
    vector <ustring> book_lines;
    for (unsigned int i = 0; i < full_book_lines.size(); i++) {
      ustring line = full_book_lines[i];
      ustring marker = usfm_extract_marker(line);
      if (usfm.is_chapter_number(marker)) {
        inrange.set_chapter (convert_to_int(number_in_string(line)));
        inrange.set_verse ("0");
      }
      if (usfm.is_verse_number(marker)) {
        size_t position = line.find(" ");
        position = CLAMP(position, 0, line.length());
        ustring verse = line.substr(0, position);
        inrange.set_verse (verse);
      }
      if (inrange.in_range()) {
        book_lines.push_back (full_book_lines[i]);
      } else {
        if (marker == "id") {
          ParseLine parseline (full_book_lines[i]);
          if (!parseline.lines.empty ()) {
            book_lines.push_back (parseline.lines[0]);
          }
        }
      }
    }

    // Do text replacements on the lines.
    text_replacement(book_lines);
    // Add the lines to the XeTeX object.
    xetex.add_book (book_id, book_lines);
  }

  // Process the data.
  ustring pdf_file = xetex.run ();

  // Display the pdf file if there is one.
  // There would be none if the formatting process was cancelled by the user.
  if (!pdf_file.empty()) {
    pdfviewer_view (pdf_file);
  }
}
Пример #8
0
void import_bibleworks_text_file (const ustring& file, const ustring& bible, vector <ustring>& messages)
// Imports a bibleworks text file.
{
  // Read the file.
  ReadText rt (file, true, false);

  // If there's nothing to import, bail out.
  if (rt.lines.empty()) {
    messages.push_back ("The file is empty");
  }

  // Divide the input into separate bits for each book.
  vector <VectorUstring> bookdata;
  if (messages.empty()) {
    try {
      ustring previousbook;
      vector < ustring > booklines;
      de_byte_order_mark (rt.lines[0]);
      for (unsigned int i = 0; i < rt.lines.size(); i++) {
        ustring currentbook = rt.lines[i].substr(0, 3);
        if (i == 0) {
          previousbook = currentbook;
        }
        if (currentbook != previousbook) {
          bookdata.push_back (booklines);
          booklines.clear();
          previousbook = currentbook;
        }
        booklines.push_back(rt.lines[i]);
      }
      bookdata.push_back (booklines);
    }
    catch(exception & ex) {
      messages.push_back(ex.what());
    }
  }

  // Import each book.
  if (messages.empty ()) {
    ProgressWindow progresswindow ("Importing", false);
    progresswindow.set_iterate (0, 1, bookdata.size());
    for (unsigned int i = 0; i < bookdata.size(); i++) {
      progresswindow.iterate ();
      try {

        // Input and output data.
        vector <ustring> rawlines = bookdata[i];
        vector <ustring> usfmlines;

        // Get the name of the book.
        unsigned int book_id = books_bibleworks_to_id(rawlines[0].substr(0, 3));
        if (book_id == 0) {
          messages.push_back ("Unknown book: " + rawlines[0]);
          return;
        }

        // Store USFM id.
        ustring usfmid = books_id_to_paratext (book_id);
        usfmlines.push_back("\\id " + usfmid);

        // Convert the BibleWorks lines to USFM code.
        ustring previouschapter = "0";
        for (unsigned int i = 0; i < rawlines.size(); i++) {
          // Convert chapter information.
          ustring line = rawlines[i];
          line.erase(0, 4);
          ustring currentchapter = number_in_string(line);
          line.erase(0, currentchapter.length() + 1);
          if (currentchapter != previouschapter) {
            usfmlines.push_back("\\c " + currentchapter);
            usfmlines.push_back("\\p");
            previouschapter = currentchapter;
          }
          // Convert verse data.
          usfmlines.push_back("\\v " + line);
        }

        // Store into the Bible.
        CategorizeChapterVerse ccv(usfmlines);
        project_store_book(bible, book_id, ccv);
        
      }
      catch(exception & ex) {
        messages.push_back(ex.what());
      }
    }
  }

}
Пример #9
0
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;  
}
Пример #10
0
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;
}
Пример #11
0
// Returns an array with the verse numbers found in $usfm.
// It handles a single verse, a range of verses, or a sequence of verses.
// It locates separate whole verse numbers.
// Examples:
// 10
// 10-12b
// 10,11a
// 10,12
vector <int> usfm_get_verse_numbers (string usfm)
{
  vector <int> verse_numbers = { 0 };
  vector <string> markers_and_text = usfm_get_markers_and_text (usfm);
  bool extract_verse = false;
  for (string marker_or_text : markers_and_text) {
    if (extract_verse) {
      string verse = usfm_peek_verse_number (marker_or_text);
      
      // If there is a range, take the beginning and the end and fill up in between.
      if (verse.find("-") != string::npos) {
        size_t position;
        position = verse.find("-");
        string start_range, end_range;
        start_range = verse.substr (0, position);
        verse.erase (0, ++position);
        end_range = verse;
        unsigned int start_verse_i = convert_to_int(number_in_string(start_range));
        unsigned int end_verse_i = convert_to_int(number_in_string(end_range));
        for (unsigned int i = start_verse_i; i <= end_verse_i; i++) {
          if (i == start_verse_i)
            verse_numbers.push_back (convert_to_int (start_range));
          else if (i == end_verse_i)
            verse_numbers.push_back (convert_to_int (end_range));
          else
            verse_numbers.push_back (i);
        }
      }
      
      // Else if there is a sequence, take each verse in the sequence, and store it.
      else if (verse.find(",") != string::npos) {
        int iterations = 0;
        do {
          // In case of an unusual range formation, do not hang, but give message.
          iterations++;
          if (iterations > 50) {
            break;
          }
          size_t position = verse.find (",");
          string vs;
          if (position == string::npos) {
            vs = verse;
            verse.clear ();
          } else {
            vs = verse.substr (0, position);
            verse.erase(0, ++position);
          }
          verse_numbers.push_back (convert_to_int (vs));
        } while (!verse.empty());
      }
      
      // No range and no sequence: a single verse.
      else {
        verse_numbers.push_back (convert_to_int (verse));
      }
      
      extract_verse = false;
    }
    if (marker_or_text.substr (0, 2) == "\\v") {
      extract_verse = true;
    }
  }
  return verse_numbers;
}
Пример #12
0
void CheckChaptersVerses::verses_check(unsigned int book, unsigned int chapter, const vector < ustring > &verses)
// This checks all the verses that are in 'book' and 'chapter'.
// It supports sequences in the form of \v 1,2,3, 
// and ranges in the form of \v 1b-3 and \v 2-4a and \v 2b-5a.
{
  // Check whether there are any verses at all. If not, stop further 
  // processing because the following code assumes there are verses.
  if (verses.empty()) {
    message(book, chapter, "1", _("Chapter has no verses"));
    return;
  }
  // Check for verses in chapter 0, which indicates the \c 1 marker wasn't there.
  if ((chapter == 0) && (verses.size() > 1)) {
    message(book, chapter, "1", _("Chapter marker missing"));
  }
  // Transform the verses in the internally used encoding, so as to accomodate
  // for sequences and ranges.
  vector < unsigned int >expanded_verses;
  vector < unsigned int >verses_pointers;
  for (unsigned int i = 0; i < verses.size(); i++) {
    // Do not work in the container, but on a copy.
    ustring vs(verses[i]);
    // If there is a range, take the beginning and the end and fill up in between.
    if (vs.find("-") != string::npos) {
      size_t position;
      position = vs.find("-");
      ustring start_range, end_range;
      start_range = vs.substr(0, position);
      vs.erase(0, ++position);
      end_range = vs;
      int start_expanded_verse = 2 * convert_to_int(number_in_string(start_range));
      if (start_range.find("b") != string::npos)
        start_expanded_verse++;
      // Checking on range start.
      if (start_range.find("a") != string::npos)
        message(book, chapter, verses[i], _("Range starts with \"a\""));
      int end_expanded_verse = 2 * convert_to_int(number_in_string(end_range));
      if (end_range.find("a") == string::npos)
        end_expanded_verse++;
      // Check on range end.
      if (end_range.find("b") != string::npos)
        message(book, chapter, verses[i], _("Range ends with \"b\""));
      for (int i2 = start_expanded_verse; i2 <= end_expanded_verse; i2++) {
        expanded_verses.push_back(i2);
        verses_pointers.push_back(i);
      }
    }
    // If there is a sequence, take each verse in the sequence, and store it.
    else if (vs.find(",") != string::npos) {
      int iterations = 0;
      do {
        // In case of an unusual range formation, do not hang, but give message.
        iterations++;
        if (iterations > 50) {
          message(book, chapter, verses[i], _("Unusual verse sequence"));
          break;
        }
        size_t position = vs.find(",");
        ustring verse;
        if (position == string::npos) {
          verse = vs;
          vs.clear();
        } else {
          verse = vs.substr(0, position);
          vs.erase(0, ++position);
        }
        store_expanded_verse(verse, i, expanded_verses, verses_pointers);
      } while (!vs.empty());
    }
    // No range and no sequence: a "normal" verse.
    else {
      store_expanded_verse(vs, i, expanded_verses, verses_pointers);
    }
  }

  // See whether it starts at verse 0 or 1.
  if (expanded_verses[0] > 2)
    message(book, chapter, verses[0], "Verse 1 missing");

  // See whether the verses are within the limit.
  for (unsigned int i = 0; i < expanded_verses.size(); i += 2) {
    unsigned int verse;
    verse = expanded_verses[i] / 2;
    if (verse > highest_verse) {
      message(book, chapter, convert_to_string(verse), _("Extra verse or wrong versification"));
    }
  }

  // See whether there are verses or bits out of sequence.
  int previous_verse = expanded_verses[0] - 1;
  for (unsigned int i = 0; i < expanded_verses.size(); i++) {
    ustring previous_verse_text;
    unsigned int pointer = verses_pointers[i];
    if (pointer == 0)
      previous_verse_text = _("beginning");
    else
      previous_verse_text = verses[pointer - 1];
    if ((int)expanded_verses[i] != previous_verse + 1) {
      message(book, chapter, verses[pointer], _("Verse out of sequence following ") + previous_verse_text);
    }
    previous_verse = expanded_verses[i];
  }

  // Check whether we have enough verses.
  int highverse = expanded_verses[expanded_verses.size() - 1];
  highverse = highverse / 2;
  if (highverse < (int)highest_verse) {
    message(book, chapter, verses[verses.size() - 1], _("Not enough verses in chapter"));
  }
  // Clear storage.
  expanded_verses.clear();
  verses_pointers.clear();
}
Пример #13
0
// Import raw $text into $bible $book $chapter.
void bible_import_text (string text, string bible, int book, int chapter)
{
  // Consecutive discoveries.
  bool discoveries_passed = true;
  
  // Split the input text into separate lines.
  vector <string> lines = filter_string_explode (text, '\n');
  
  // Go through the lines.
  for (size_t i = 0; i < lines.size(); i++) {
    
    // Trim the line.
    lines[i] = filter_string_trim (lines[i]);
    
    // Skip empty line.
    if (lines[i].empty())
      continue;
    
    // Remove chapter markup.
    if (lines[i].find("\\c") != string::npos) {
      lines[i].clear();
      continue;
    }
    
    // Skip line starting with a backslash. The rationale is that this line already has markup.
    if (lines[i].substr(0, 1) == "\\")
      continue;
    
    // If the line is a number on its own, and the number agrees with the chapter number
    // that was set, it silently removes this line. But if it differs, an error comes up.
    if (discoveries_passed) {
      if (number_in_string(lines[i]) == lines[i]) {
        int number = convert_to_int (number_in_string (lines[i]));
        if (number == chapter) {
          lines[i].clear();
          continue;
        }
        string msg = "The line that contains " + lines[i] + " looks like a chapter number, but the number differs from the chapter that was set";
        Database_Logs::log (msg);
        discoveries_passed = false;
      }
    }
    
    // If the line has no number in it,
    // and it ends with some type of punctuation,
    // it is considered a a normal paragraph.
    // If no punctuation at the end, it is a section heading.
    if (discoveries_passed) {
      if (number_in_string(lines[i]).empty()) {
        string last_character = lines[i].substr(lines[i].length() -1, 1);
        if (unicode_string_is_punctuation (last_character)) {
          lines[i].insert(0, "\\p ");
        } else {
          lines[i].insert(0, "\\s ");
        }
        continue;
      }
    }
    
    // If a number is found in the line, then this is considered a verse number.
    // The first time a number is found, a \p is prefixed.
    bool paragraph_open = false;
    if (discoveries_passed) {
      string output;
      string number = number_in_string(lines[i]);
      // Setting for having the number only at the start of the line.
      bool treat_as_normal_paragraph = false;
      bool verses_at_start = true;
      if (verses_at_start) {
        if (lines[i].find (number) != 0) {
          number.clear();
          treat_as_normal_paragraph = true;
        }
      }
      if (treat_as_normal_paragraph) {
        
        // Normal paragraph.
        lines[i].insert(0, "\\p ");
        
      } else {
        
        // Find all verse numbers.
        while (!number.empty()) {
          if (!paragraph_open) {
            output.append("\\p");
            paragraph_open = true;
          }
          size_t pos = lines[i].find(number);
          if (pos > 0) {
            output.append(" " + lines[i].substr(0, pos));
            lines[i].erase(0, pos);
          }
          output.append ("\n\\v ");
          output.append (number);
          output.append (" ");
          lines[i].erase (0, number.length());
          lines[i] = filter_string_trim (lines[i]);
          number = number_in_string(lines[i]);
          // Setting for discovering only first number in a paragraph.
          if (verses_at_start) {
            number.clear();
          }
        }
        
      }
      // Store line.
      output.append(lines[i]);
      lines[i] = output;
    }
    
  }
  
  // Make one block of text.
  string newtext;
  for (unsigned int i = 0; i < lines.size(); i++) {
    if (lines[i].empty())
      continue;
    filter_string_str_replace ("  ", " ", lines[i]);
    filter_string_str_replace (" \n", "\n", lines[i]);
    newtext.append(lines[i]);
    newtext.append("\n");
  }
  
  // If no chapter marker is found, insert it at the top.
  if (newtext.find("\\c") == string::npos) {
    newtext.insert(0, "\\c " + convert_to_string(chapter) + "\n");
  }

  // Import the text as USFM.
  bible_logic_store_chapter (bible, book, chapter, newtext);
  string book_name = Database_Books::getUsfmFromId (book);
  Database_Logs::log ("Imported " + book_name + " " + convert_to_string (chapter) + ": " + text);
}
Пример #14
0
void CheckValidateReferences::check(const ustring & text)
// Do the actual check of one verse.
{
  // Bail out if the verse is empty.
  if (text.empty())
    return;

  // Extract the references and check them all.
  ReferencesScanner refscanner(language, book, text);
  for (unsigned int i = 0; i < references.size(); i++) {

    // Check whether the reference fits within the limits of the versification system.
    bool reference_fits = true;
    unsigned int highest_chapter = 0;
    vector < unsigned int >chapters = versification_get_chapters(versification, refscanner.references[i].book_get());
    if (!chapters.empty())
      highest_chapter = chapters[chapters.size() - 1];
    if (refscanner.references[i].chapter_get() > highest_chapter)
      reference_fits = false;
    unsigned int last_verse = convert_to_int(versification_get_last_verse(versification, 
									  refscanner.references[i].book_get(),
									  refscanner.references[i].chapter_get()));
    unsigned int this_verse = convert_to_int(refscanner.references[i].verse_get());
    if (this_verse > last_verse)
      reference_fits = false;
    if (!reference_fits) {
      message(refscanner.references[i].human_readable(language) + _(" does not fit in the versification system"));
    }
    // Check whether the reference exists in the project.
    if (reference_fits) {
      ustring versetext = project_retrieve_verse(myproject, refscanner.references[i]);
      if (versetext.empty()) {
        message(refscanner.references[i].human_readable(language) + _(" contains no text"));
      }
    }
  }

  // Look for chapter/verse pairs by pattern, and check on these.
  ustring mytext(text);
  while (mytext.length() > 5) {
    if (text_starts_chapter_verse(mytext)) {
      // This text starts a chapter/verse string.
      // Look for the dot or colon.
      size_t position = mytext.find_first_of(".:");
      if (position != string::npos) {
        unsigned int mychapter = convert_to_int(mytext.substr(0, position));
        mytext.erase(0, ++position);
        ustring myverse = number_in_string(mytext);
        mytext.erase(0, myverse.length());
        bool referencefound = false;
        for (unsigned int i = 0; i < references.size(); i++) {
          if (refscanner.references[i].chapter_get() == mychapter)
            if (refscanner.references[i].verse_get() == myverse)
              referencefound = true;
        }
        if (!referencefound) {
          message(_("Unrecognized chapter ") + convert_to_string(mychapter) + _(" and verse ") + myverse);
        }
      }
      mytext.erase(0, 3);
    } else {
      // No chapter/verse string: erase one character and try again.
      mytext.erase(0, 1);
    }
  }
}