postiffm / bibledit-desktop

Desktop version of Bibledit
GNU General Public License v3.0
4 stars 6 forks source link

Apparatus feature #63

Closed Pickle closed 5 years ago

Pickle commented 5 years ago

Added apparatus tab to the analysis window. Added code to load apparatus for sblgnt Removed hardcoded bible count and adapted to dynamically handle bibles and apparatus.

postiffm commented 5 years ago

Nice looking code!

postiffm commented 5 years ago

I think there is a bug. If you visit Matthew 1:25, the apparatus data is displayed correctly. But if you try Matthew 2:3, it says it is out of range. This happens in Mark and Revelation as well, and I have not tested others. I suspect it is because in the data files, after 1:25, there is a blank line. The same type of thing happens in the Mark data as well as the Revelation data.

Headed into the book loading code right now to see what is up.

postiffm commented 5 years ago

Just a couple of things that weren't too hard to find. I added a feature to the ReadText object to instruct it to drop blank lines. Key change was when a new chapter number is encountered, we have to reset the verse number to 0 so that the first verses in the chapter--if they have no apparatus data--are filled with the default "no apparatus for this verse" message.

$ git diff
diff --git a/src/biblebookchapterverse.cpp b/src/biblebookchapterverse.cpp
index 2429c22..c93c2a6 100644
--- a/src/biblebookchapterverse.cpp
+++ b/src/biblebookchapterverse.cpp
@@ -525,7 +525,7 @@ void book_sblgntapp::load(void)
     }

     //  From utilities.cpp
-    ReadText rt(Directories->get_package_data() + "/bibles/sblgnt/" + filenames[bookidx], /*silent*/false, /*trimming*/true);
+    ReadText rt(Directories->get_package_data() + "/bibles/sblgnt/" + filenames[bookidx], /*silent*/false, /*trimAll*/true, /*trimEnd*/true, /*supressBlanks*/true);
     unsigned int currchapnum = 0;
     unsigned int currversenum = 0;
     chapter *currchap = NULL;
@@ -533,27 +533,36 @@ void book_sblgntapp::load(void)

     //  builds the chapters verse by verse
     for (auto &it: rt.lines) {
-         // First line is title of book, we don't need them
-         if (linecnt == 0) { linecnt++; continue; }
+         // First lines are boilerplate, like this:
+         // <blank>
+         // Matthew Apparatus Data
+         // Order of edition citation: WH Treg NIV RP
+         // <blank>
+         if (linecnt <= 3) { linecnt++; continue; }
          //  Extract chapter and verse,  and leading space. The lines are always
          //  well formed: Book<space>1:5<tab>Verse text.
          //  Remove book name from the line
          size_t spaceposition = it.find_first_of(" ");
          it.erase(0,  spaceposition+1);
+         // Extract chapter number
          size_t colonposition = it.find_first_of(":");
          ustring chapstring = it.substr(0,  colonposition);
          unsigned int chapnum = convert_to_int(chapstring);
+         // Extract verse number
          size_t tabposition = it.find_first_of("\t");
          ustring versestring = it.substr(colonposition+1, tabposition-colonposition-1);
          unsigned int versenum = convert_to_int(versestring);
+         // Erase everything up to and including the tab
          it.erase(0, tabposition+1);
          if ((chapnum != currchapnum) && (currchapnum-chapnum > 0)) {
+           // "Fill in" blank chapter numbers
            for (i=currchapnum+1; i<=chapnum; i++) {
              chapter *newchap = new chapter(this, i);
              chapters.push_back(newchap);
              currchap = newchap;
            }
            currchapnum = chapnum;
+           currversenum = 0; // when we get to a new chapter, have to reset the verse number

            cerr << "Created new chapter " << chapnum << " from " << filenames[bookidx] << endl;
          }
@@ -561,7 +570,7 @@ void book_sblgntapp::load(void)
          if ((versenum != currversenum) && (versenum-currversenum>0)) {
            if (versenum-currversenum>1) {
            for (i=currversenum+1; i<versenum; i++) {
-             verse *newverse = new verse(currchap, i, ustring("No apparatus notes for this verse")); //  takes a copy of the ustring text (it)
+             verse *newverse = new verse(currchap, i, ustring("No apparatus notes for ") + std::to_string(chapnum) + ":" + std::to_string(i)); //  takes a copy of the ustring text (it)
              currchap->verses.push_back(newverse); //  append verse to current chapter
              newverse->print(); // debug
            }
diff --git a/src/utilities.cpp b/src/utilities.cpp
index d3e1bd5..886d011 100644
--- a/src/utilities.cpp
+++ b/src/utilities.cpp
@@ -503,11 +503,12 @@ ReadFiles::~ReadFiles()
 }

-ReadText::ReadText(const ustring & file, bool silent, bool trimAll, bool trimEnding)
+ReadText::ReadText(const ustring & file, bool silent, bool trimAll, bool trimEnding, bool supressBlanks)
 {
-  // Reads the text and stores it line by line, trimmed, into "lines".
-  // If "silent" is true, then no exception will be thrown in case of an error.
-  // The lines will be trimmed if "trimming" is true.
+  // Reads the text and stores it line by line, trimmed, into lines storage.
+  // If silent is true, then no exception will be thrown in case of an error.
+  // If trimAll is true, whitespace at beginningn and end will be trimmed off.
+  // If trimEnding is true, whitespace at end will be trimmed off.
   ifstream in(file.c_str());
   if (!in) {
     if (!silent) {
@@ -524,7 +525,10 @@ ReadText::ReadText(const ustring & file, bool silent, bool trimAll, bool trimEnd
     else if (trimEnding) {
       s = trimEnd(s);
     }
-    lines.push_back(s);
+    if (supressBlanks && (s == "")) {
+        // this is a blank line that we don't want to see
+    }
+    else { lines.push_back(s); } // most times, this line will execute
   }
 }

diff --git a/src/utilities.h b/src/utilities.h
index 002707b..4bc3558 100644
--- a/src/utilities.h
+++ b/src/utilities.h
@@ -78,7 +78,7 @@ private:
 class ReadText
 {
 public:
-  ReadText (const ustring & file, bool silent = false, bool trimAll = true, bool trimEnding=false);
+  ReadText (const ustring & file, bool silent = false, bool trimAll = true, bool trimEnding=false, bool supressBlanks=false);
   ~ReadText ();
   vector < ustring > lines;
 private:
postiffm commented 5 years ago

Seg fault on program close--the destructor ran amok with a faulty termination in the for loops.

$ git diff
diff --git a/src/referencebibles.cpp b/src/referencebibles.cpp
index 8f25a3c..3bb4d84 100644
--- a/src/referencebibles.cpp
+++ b/src/referencebibles.cpp
@@ -46,12 +46,12 @@ ReferenceBibles::~ReferenceBibles()
 {
   uint8_t i;

-  for (i=0; bibles.size(); i++) {
+  for (i=0; i < bibles.size(); i++) {
     delete bibles.at(i);
   }
   bibles.clear();

-  for (i=0; apparatus.size(); i++) {
+  for (i=0; i < apparatus.size(); i++) {
     delete apparatus.at(i);
   }
   apparatus.clear();