~bibledit/bibledit/ubuntu-cloud-beta

« back to all changes in this revision

Viewing changes to filter/text.cpp

  • Committer: Teus Benschop
  • Date: 2022-10-14 16:03:26 UTC
  • Revision ID: teusjannette@gmail.com-20221014160326-42ybrpft4bblpruk
new upstream version

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
// This class filters USFM text, converting it into other formats.
47
47
 
48
48
 
49
 
Filter_Text::Filter_Text (string bible_in)
 
49
Filter_Text::Filter_Text (string bible)
50
50
{
51
 
  bible = bible_in;
52
 
  currentBookIdentifier = 0;
53
 
  currentChapterNumber = 0;
54
 
  heading_started = false;
55
 
  text_started = false;
56
 
  odf_text_standard = nullptr;
57
 
  odf_text_text_only = nullptr;
58
 
  odf_text_text_and_note_citations = nullptr;
59
 
  odf_text_notes = nullptr;
60
 
  html_text_standard = nullptr;
61
 
  html_text_linked = nullptr;
62
 
  onlinebible_text = nullptr;
63
 
  esword_text = nullptr;
64
 
  text_text = nullptr;
65
 
  tbsx_text = nullptr;
66
 
  headings_text_per_verse_active = false;
67
 
  space_type_after_verse = Database_Config_Bible::getOdtSpaceAfterVerse (bible);
68
 
  is_within_figure_markup = false;
69
 
  odt_left_align_verse_in_poetry_styles = Database_Config_Bible::getOdtPoetryVersesLeft (bible);
 
51
  m_bible = bible;
 
52
  space_type_after_verse = Database_Config_Bible::getOdtSpaceAfterVerse (m_bible);
 
53
  odt_left_align_verse_in_poetry_styles = Database_Config_Bible::getOdtPoetryVersesLeft (m_bible);
70
54
}
71
55
 
72
56
 
99
83
  usfm = filter_string_trim (usfm);
100
84
  usfm += "\n";
101
85
  // Sort the USFM code out and separate it into markers and text.
102
 
  vector <string> markersAndText = filter::usfm::get_markers_and_text (usfm);
 
86
  vector <string> markers_and_text = filter::usfm::get_markers_and_text (usfm);
103
87
  // Add the USFM to the object.
104
 
  usfmMarkersAndText.insert (usfmMarkersAndText.end(), markersAndText.begin(), markersAndText.end());
 
88
  m_usfm_markers_and_text.insert (m_usfm_markers_and_text.end(), markers_and_text.begin(), markers_and_text.end());
105
89
}
106
90
 
107
91
 
111
95
void Filter_Text::run (string stylesheet)
112
96
{
113
97
  // Get the styles.
114
 
  getStyles (stylesheet);
 
98
  get_styles (stylesheet);
115
99
 
116
100
  // Preprocess.
117
101
  pre_process_usfm ();
119
103
  // Process data.
120
104
  process_usfm ();
121
105
 
122
 
  storeVersesParagraphs ();
 
106
  store_verses_paragraphs ();
123
107
  
124
108
  // Clear USFM and styles.
125
 
  usfmMarkersAndText.clear();
126
 
  usfmMarkersAndTextPointer = 0;
 
109
  m_usfm_markers_and_text.clear();
 
110
  usfm_markers_and_text_ptr = 0;
127
111
  chapter_usfm_markers_and_text.clear();
128
112
  chapter_usfm_markers_and_text_pointer = 0;
129
113
  styles.clear();
134
118
 
135
119
 
136
120
// This function return true when there is still unprocessed USFM code available.
137
 
bool Filter_Text::unprocessedUsfmCodeAvailable ()
 
121
bool Filter_Text::unprocessed_usfm_code_available ()
138
122
{
139
 
  return (usfmMarkersAndTextPointer < usfmMarkersAndText.size());
 
123
  return (usfm_markers_and_text_ptr < m_usfm_markers_and_text.size());
140
124
}
141
125
 
142
126
 
143
127
 
144
128
// This function stores data in the class:
145
129
// The next chapter from the unprocessed USFM code.
146
 
void Filter_Text::getUsfmNextChapter ()
 
130
void Filter_Text::get_usfm_next_chapter ()
147
131
{
148
132
  // Initialization.
149
133
  chapter_usfm_markers_and_text.clear();
163
147
  }
164
148
 
165
149
  // Load the USFM code till the next chapter marker.
166
 
  while (unprocessedUsfmCodeAvailable ()) {
167
 
    string item = usfmMarkersAndText [usfmMarkersAndTextPointer];
 
150
  while (unprocessed_usfm_code_available ()) {
 
151
    string item = m_usfm_markers_and_text [usfm_markers_and_text_ptr];
168
152
    if (!firstLine) {
169
153
      if (filter_string_trim (item) == (R"(\)" + chapterMarker)) {
170
154
        return;
172
156
    }
173
157
    chapter_usfm_markers_and_text.push_back (item);
174
158
    firstLine = false;
175
 
    usfmMarkersAndTextPointer++;
 
159
    usfm_markers_and_text_ptr++;
176
160
  }
177
161
}
178
162
 
180
164
 
181
165
// This function gets the styles from the database,
182
166
// and stores them in the object for quicker access.
183
 
void Filter_Text::getStyles (string stylesheet)
 
167
void Filter_Text::get_styles (string stylesheet)
184
168
{
185
169
  styles.clear();
186
170
  // Get the relevant styles information included.
212
196
// extracting a variety of information, creating note citations, etc.
213
197
void Filter_Text::pre_process_usfm ()
214
198
{
215
 
  usfmMarkersAndTextPointer = 0;
216
 
  while (unprocessedUsfmCodeAvailable ()) {
217
 
    getUsfmNextChapter ();
 
199
  usfm_markers_and_text_ptr = 0;
 
200
  while (unprocessed_usfm_code_available ()) {
 
201
    get_usfm_next_chapter ();
218
202
    for (chapter_usfm_markers_and_text_pointer = 0; chapter_usfm_markers_and_text_pointer < chapter_usfm_markers_and_text.size(); chapter_usfm_markers_and_text_pointer++) {
219
203
      string currentItem = chapter_usfm_markers_and_text[chapter_usfm_markers_and_text_pointer];
220
204
      if (filter::usfm::is_usfm_marker (currentItem)) {
233
217
                    string usfm_id = filter::usfm::get_book_identifier (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
234
218
                    usfm_id = filter_string_str_replace (soft_hyphen_u00AD (), "", usfm_id); // Remove possible soft hyphen.
235
219
                    // Get Bibledit book number.
236
 
                    currentBookIdentifier = database::books::get_id_from_usfm (usfm_id);
 
220
                    m_current_book_identifier = database::books::get_id_from_usfm (usfm_id);
237
221
                    // Reset chapter and verse numbers.
238
 
                    currentChapterNumber = 0;
239
 
                    numberOfChaptersPerBook[currentBookIdentifier] = 0;
 
222
                    m_current_chapter_number = 0;
 
223
                    numberOfChaptersPerBook[m_current_book_identifier] = 0;
240
224
                    currentVerseNumber = "0";
241
225
                    // Done.
242
226
                    break;
244
228
                  case IdentifierSubtypeRunningHeader:
245
229
                  {
246
230
                    string runningHeader = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
247
 
                    runningHeaders.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, runningHeader));
 
231
                    runningHeaders.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, runningHeader));
248
232
                    break;
249
233
                  }
250
234
                  case IdentifierSubtypeLongTOC:
251
235
                  {
252
236
                    string longTOC = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
253
 
                    longTOCs.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, longTOC));
 
237
                    longTOCs.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, longTOC));
254
238
                    break;
255
239
                  }
256
240
                  case IdentifierSubtypeShortTOC:
257
241
                  {
258
242
                    string shortTOC = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
259
 
                    shortTOCs.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, shortTOC));
 
243
                    shortTOCs.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, shortTOC));
260
244
                    break;
261
245
                  }
262
246
                  case IdentifierSubtypeBookAbbrev:
263
247
                  {
264
248
                    string bookAbbreviation = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
265
 
                    bookAbbreviations.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, bookAbbreviation));
 
249
                    bookAbbreviations.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, bookAbbreviation));
266
250
                    break;
267
251
                  }
268
252
                  case IdentifierSubtypeChapterLabel:
269
253
                  {
270
254
                    // Store the chapter label for this book and chapter.
271
255
                    string chapterLabel = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
272
 
                    chapterLabels.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, chapterLabel));
 
256
                    chapterLabels.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, chapterLabel));
273
257
                    // If a chapter label is in the book, there's no drop caps output of the chapter number.
274
 
                    book_has_chapter_label [currentBookIdentifier] = true;
 
258
                    book_has_chapter_label [m_current_book_identifier] = true;
275
259
                    // Done.
276
260
                    break;
277
261
                  }
278
262
                  case IdentifierSubtypePublishedChapterMarker:
279
263
                  {
280
264
                    string publishedChapterMarker = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
281
 
                    publishedChapterMarkers.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, publishedChapterMarker));
 
265
                    publishedChapterMarkers.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, publishedChapterMarker));
282
266
                    break;
283
267
                  }
284
268
                  case IdentifierSubtypePublishedVerseMarker:
287
271
                    // The marker looks like: ... \vp ၁။\vp* ...
288
272
                    // It stores this markup in the object for later reference.
289
273
                    string publishedVerseMarker = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
290
 
                    publishedVerseMarkers.push_back (filter::text::passage_marker_value (currentBookIdentifier, currentChapterNumber, currentVerseNumber, marker, publishedVerseMarker));
 
274
                    publishedVerseMarkers.push_back (filter::text::passage_marker_value (m_current_book_identifier, m_current_chapter_number, currentVerseNumber, marker, publishedVerseMarker));
291
275
                    break;
292
276
                  }
293
277
                  default: break;
296
280
              case StyleTypeChapterNumber:
297
281
              {
298
282
                string number = filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
299
 
                currentChapterNumber = convert_to_int (number);
300
 
                numberOfChaptersPerBook[currentBookIdentifier] = currentChapterNumber;
 
283
                m_current_chapter_number = convert_to_int (number);
 
284
                numberOfChaptersPerBook[m_current_book_identifier] = m_current_chapter_number;
301
285
                currentVerseNumber = "0";
302
286
                break;
303
287
              }
356
340
void Filter_Text::process_usfm ()
357
341
{
358
342
  // Go through the USFM code.
359
 
  int processedBooksCount = 0;
360
 
  usfmMarkersAndTextPointer = 0;
361
 
  while (unprocessedUsfmCodeAvailable ()) {
362
 
    getUsfmNextChapter ();
 
343
  int processed_books_count {0};
 
344
  usfm_markers_and_text_ptr = 0;
 
345
  while (unprocessed_usfm_code_available ()) {
 
346
    get_usfm_next_chapter ();
363
347
    for (chapter_usfm_markers_and_text_pointer = 0; chapter_usfm_markers_and_text_pointer < chapter_usfm_markers_and_text.size(); chapter_usfm_markers_and_text_pointer++) {
364
348
      string currentItem = chapter_usfm_markers_and_text [chapter_usfm_markers_and_text_pointer];
365
349
      if (filter::usfm::is_usfm_marker (currentItem))
366
350
      {
367
351
        // Indicator describing the marker.
368
 
        bool isOpeningMarker = filter::usfm::is_opening_marker (currentItem);
369
 
        bool isEmbeddedMarker = filter::usfm::is_embedded_marker (currentItem);
 
352
        bool is_opening_marker = filter::usfm::is_opening_marker (currentItem);
 
353
        bool is_embedded_marker = filter::usfm::is_embedded_marker (currentItem);
370
354
        // Clean up the marker, so we remain with the basic version, e.g. 'id'.
371
355
        string marker = filter::usfm::get_marker (currentItem);
372
356
        // Strip word-level attributes.
373
 
        if (isOpeningMarker) filter::usfm::remove_word_level_attributes (marker, chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
 
357
        if (is_opening_marker) filter::usfm::remove_word_level_attributes (marker, chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
374
358
        if (styles.find (marker) != styles.end())
375
359
        {
376
360
          // Deal with known style.
392
376
                  // Get book number.
393
377
                  string usfm_id = filter::usfm::get_book_identifier (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
394
378
                  usfm_id = filter_string_str_replace (soft_hyphen_u00AD (), "", usfm_id); // Remove possible soft hyphen.
395
 
                  currentBookIdentifier = database::books::get_id_from_usfm (usfm_id);
 
379
                  m_current_book_identifier = database::books::get_id_from_usfm (usfm_id);
396
380
                  // Reset chapter and verse numbers.
397
 
                  currentChapterNumber = 0;
 
381
                  m_current_chapter_number = 0;
398
382
                  currentVerseNumber = "0";
399
383
                  // Throw away whatever follows the \id, e.g. 'GEN xxx xxx'.
400
384
                  filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
401
385
                  // Whether to insert a new page before the book. But never before the first book.
402
386
                  if (style.userbool1) {
403
 
                    if (processedBooksCount) {
 
387
                    if (processed_books_count) {
404
388
                      if (odf_text_standard) odf_text_standard->new_page_break ();
405
389
                      if (odf_text_text_only) odf_text_text_only->new_page_break ();
406
390
                      if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_page_break ();
408
392
                      if (html_text_linked) html_text_linked->new_page_break ();
409
393
                    }
410
394
                  }
411
 
                  processedBooksCount++;
 
395
                  processed_books_count++;
412
396
                  // Reset notes.
413
397
                  note_citations.restart("book");
414
398
                  // Online Bible.
415
399
                  if (onlinebible_text) onlinebible_text->storeData ();
416
400
                  // eSword.
417
 
                  if (esword_text) esword_text->newBook (currentBookIdentifier);
 
401
                  if (esword_text) esword_text->newBook (m_current_book_identifier);
418
402
                  // The hidden header in the text normally displays in the running header.
419
403
                  // It does this only when it's the first header on the page.
420
404
                  // The book starts here.
421
405
                  // So create a correct hidden header for displaying in the running header.
422
 
                  string runningHeader = database::books::get_english_from_id (currentBookIdentifier);
 
406
                  string runningHeader = database::books::get_english_from_id (m_current_book_identifier);
423
407
                  for (auto item : runningHeaders) {
424
 
                    if (item.m_book == currentBookIdentifier) {
 
408
                    if (item.m_book == m_current_book_identifier) {
425
409
                      runningHeader = item.m_value;
426
410
                    }
427
411
                  }
487
471
                }
488
472
                case IdentifierSubtypeCommentWithEndmarker:
489
473
                {
490
 
                  if (isOpeningMarker) {
 
474
                  if (is_opening_marker) {
491
475
                    addToInfo (R"(Comment: \)" + marker, true);
492
476
                  }
493
477
                  break;
494
478
                }
495
479
                case IdentifierSubtypePublishedVerseMarker:
496
480
                {
497
 
                  if (isOpeningMarker) {
 
481
                  if (is_opening_marker) {
498
482
                    // This information is already in the object.
499
483
                    // Remove it from the USFM stream at the opening marker.
500
484
                    filter::usfm::get_text_following_marker (chapter_usfm_markers_and_text, chapter_usfm_markers_and_text_pointer);
565
549
                    // Record the style that started this new paragraph.
566
550
                    paragraph_starting_markers.push_back (style.marker);
567
551
                    // Store previous paragraph, if any, and start recording the new one.
568
 
                    storeVersesParagraphs ();
 
552
                    store_verses_paragraphs ();
569
553
                  }
570
554
                  break;
571
555
                }
575
559
            case StyleTypeInlineText:
576
560
            {
577
561
              // Support for a normal and an embedded character style.
578
 
              if (isOpeningMarker) {
579
 
                if (odf_text_standard) odf_text_standard->open_text_style (style, false, isEmbeddedMarker);
580
 
                if (odf_text_text_only) odf_text_text_only->open_text_style (style, false, isEmbeddedMarker);
581
 
                if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->open_text_style (style, false, isEmbeddedMarker);
582
 
                if (html_text_standard) html_text_standard->open_text_style (style, false, isEmbeddedMarker);
583
 
                if (html_text_linked) html_text_linked->open_text_style (style, false, isEmbeddedMarker);
 
562
              if (is_opening_marker) {
 
563
                if (odf_text_standard) odf_text_standard->open_text_style (style, false, is_embedded_marker);
 
564
                if (odf_text_text_only) odf_text_text_only->open_text_style (style, false, is_embedded_marker);
 
565
                if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->open_text_style (style, false, is_embedded_marker);
 
566
                if (html_text_standard) html_text_standard->open_text_style (style, false, is_embedded_marker);
 
567
                if (html_text_linked) html_text_linked->open_text_style (style, false, is_embedded_marker);
584
568
              } else {
585
 
                if (odf_text_standard) odf_text_standard->close_text_style (false, isEmbeddedMarker);
586
 
                if (odf_text_text_only) odf_text_text_only->close_text_style (false, isEmbeddedMarker);
587
 
                if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, isEmbeddedMarker);
588
 
                if (html_text_standard) html_text_standard->close_text_style (false, isEmbeddedMarker);
589
 
                if (html_text_linked) html_text_linked->close_text_style (false, isEmbeddedMarker);
 
569
                if (odf_text_standard) odf_text_standard->close_text_style (false, is_embedded_marker);
 
570
                if (odf_text_text_only) odf_text_text_only->close_text_style (false, is_embedded_marker);
 
571
                if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->close_text_style (false, is_embedded_marker);
 
572
                if (html_text_standard) html_text_standard->close_text_style (false, is_embedded_marker);
 
573
                if (html_text_linked) html_text_linked->close_text_style (false, is_embedded_marker);
590
574
              }
591
575
              break;
592
576
            }
606
590
              int inumber = convert_to_int (number);
607
591
 
608
592
              // Update this object.
609
 
              currentChapterNumber = inumber;
 
593
              m_current_chapter_number = inumber;
610
594
              currentVerseNumber = "0";
611
595
 
612
596
              // If there is a published chapter character, the chapter number takes that value.
613
597
              for (auto publishedChapterMarker : publishedChapterMarkers) {
614
 
                if (publishedChapterMarker.m_book == currentBookIdentifier) {
615
 
                  if (publishedChapterMarker.m_chapter == currentChapterNumber) {
 
598
                if (publishedChapterMarker.m_book == m_current_book_identifier) {
 
599
                  if (publishedChapterMarker.m_chapter == m_current_chapter_number) {
616
600
                    number = publishedChapterMarker.m_value;
617
601
                    inumber = convert_to_int (number);
618
602
                  }
620
604
              }
621
605
 
622
606
              // Enter text for the running headers.
623
 
              string runningHeader = database::books::get_english_from_id (currentBookIdentifier);
 
607
              string runningHeader = database::books::get_english_from_id (m_current_book_identifier);
624
608
              for (auto item : runningHeaders) {
625
 
                if (item.m_book == currentBookIdentifier) {
 
609
                if (item.m_book == m_current_book_identifier) {
626
610
                  runningHeader = item.m_value;
627
611
                }
628
612
              }
638
622
                text_text->paragraph (number);
639
623
              }
640
624
              // The chapter number is only output when there is more than one chapter in a book.
641
 
              if (numberOfChaptersPerBook [currentBookIdentifier] > 1) {
 
625
              if (numberOfChaptersPerBook [m_current_book_identifier] > 1) {
642
626
                // Putting the chapter number at the first verse is determined by the style of the \c marker.
643
627
                // But if a chapter label (\cl) is found in the current book, that disables the above.
644
 
                bool cl_found = book_has_chapter_label[currentBookIdentifier];
 
628
                bool cl_found = book_has_chapter_label[m_current_book_identifier];
645
629
                if (style.userbool1 && !cl_found) {
646
630
                  // Output the chapter number at the first verse, not here.
647
631
                  // Store it for later processing.
656
640
                  string labelEntireBook {};
657
641
                  string labelCurrentChapter {};
658
642
                  for (auto pchapterLabel : chapterLabels) {
659
 
                    if (pchapterLabel.m_book == currentBookIdentifier) {
 
643
                    if (pchapterLabel.m_book == m_current_book_identifier) {
660
644
                      if (pchapterLabel.m_chapter == 0) {
661
645
                        labelEntireBook = pchapterLabel.m_value;
662
646
                      }
663
 
                      if (pchapterLabel.m_chapter == currentChapterNumber) {
 
647
                      if (pchapterLabel.m_chapter == m_current_chapter_number) {
664
648
                        labelCurrentChapter = pchapterLabel.m_value;
665
649
                      }
666
650
                    }
683
667
              }
684
668
 
685
669
              // Output chapter number for other formats.
686
 
              if (esword_text) esword_text->newChapter (currentChapterNumber);
687
 
              if (tbsx_text) tbsx_text->set_chapter(currentChapterNumber);
 
670
              if (esword_text) esword_text->newChapter (m_current_chapter_number);
 
671
              if (tbsx_text) tbsx_text->set_chapter(m_current_chapter_number);
688
672
 
689
673
              // Open a paragraph for the notes.
690
674
              // It takes the style of the footnote content marker, usually 'ft'.
712
696
              // Handle a situation that a verse number starts a new paragraph.
713
697
              if (style.userbool1) {
714
698
                if (odf_text_standard) {
715
 
                  if (!odf_text_standard->current_paragraph_content.empty()) {
716
 
                    odf_text_standard->new_paragraph (odf_text_standard->current_paragraph_style);
 
699
                  if (!odf_text_standard->m_current_paragraph_content.empty()) {
 
700
                    odf_text_standard->new_paragraph (odf_text_standard->m_current_paragraph_style);
717
701
                  }
718
702
                }
719
703
                if (odf_text_text_only) {
720
 
                  if (!odf_text_text_only->current_paragraph_content.empty()) {
721
 
                    odf_text_text_only->new_paragraph (odf_text_text_only->current_paragraph_style);
 
704
                  if (!odf_text_text_only->m_current_paragraph_content.empty()) {
 
705
                    odf_text_text_only->new_paragraph (odf_text_text_only->m_current_paragraph_style);
722
706
                  }
723
707
                }
724
708
                if (odf_text_text_and_note_citations) {
725
 
                  if (!odf_text_text_and_note_citations->current_paragraph_content.empty()) {
726
 
                    odf_text_text_and_note_citations->new_paragraph (odf_text_text_and_note_citations->current_paragraph_style);
 
709
                  if (!odf_text_text_and_note_citations->m_current_paragraph_content.empty()) {
 
710
                    odf_text_text_and_note_citations->new_paragraph (odf_text_text_and_note_citations->m_current_paragraph_style);
727
711
                  }
728
712
                }
729
713
                if (html_text_standard) {
742
726
              }
743
727
              // Deal with the case of a pending chapter number.
744
728
              if (!output_chapter_text_at_first_verse.empty()) {
745
 
                if (!Database_Config_Bible::getExportChapterDropCapsFrames (bible)) {
 
729
                if (!Database_Config_Bible::getExportChapterDropCapsFrames (m_bible)) {
746
730
                  int dropCapsLength = static_cast<int>(unicode_string_length (output_chapter_text_at_first_verse));
747
731
                  applyDropCapsToCurrentParagraph (dropCapsLength);
748
732
                  if (odf_text_standard) odf_text_standard->add_text (output_chapter_text_at_first_verse);
768
752
              // In case there was a published verse marker, use that markup for publishing.
769
753
              string v_vp_number = v_number;
770
754
              for (auto publishedVerseMarker : publishedVerseMarkers) {
771
 
                if (publishedVerseMarker.m_book == currentBookIdentifier) {
772
 
                  if (publishedVerseMarker.m_chapter == currentChapterNumber) {
 
755
                if (publishedVerseMarker.m_book == m_current_book_identifier) {
 
756
                  if (publishedVerseMarker.m_chapter == m_current_chapter_number) {
773
757
                    if (publishedVerseMarker.m_verse == currentVerseNumber) {
774
758
                      v_vp_number = publishedVerseMarker.m_value;
775
759
                    }
780
764
              if (output_chapter_text_at_first_verse.empty ()) {
781
765
                // If the current paragraph has text already, then insert a space.
782
766
                if (odf_text_standard) {
783
 
                  if (!odf_text_standard->current_paragraph_content.empty()) {
 
767
                  if (!odf_text_standard->m_current_paragraph_content.empty()) {
784
768
                    odf_text_standard->add_text (" ");
785
769
                  }
786
770
                }
787
771
                if (odf_text_text_only) {
788
 
                  if (!odf_text_text_only->current_paragraph_content.empty()) {
 
772
                  if (!odf_text_text_only->m_current_paragraph_content.empty()) {
789
773
                    odf_text_text_only->add_text (" ");
790
774
                  }
791
775
                }
792
776
                if (odf_text_text_and_note_citations) {
793
 
                  if (!odf_text_text_and_note_citations->current_paragraph_content.empty()) {
 
777
                  if (!odf_text_text_and_note_citations->m_current_paragraph_content.empty()) {
794
778
                    odf_text_text_and_note_citations->add_text (" ");
795
779
                  }
796
780
                }
853
837
                // If a chapter number was put, do not output any white space.
854
838
                if (output_chapter_text_at_first_verse.empty()) {
855
839
                  if (odf_text_standard) {
856
 
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_standard->current_paragraph_style);
 
840
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_standard->m_current_paragraph_style);
857
841
                    if (tab) odf_text_standard->add_tab();
858
842
                    else odf_text_standard->add_text (space_type_after_verse);
859
843
                  }
860
844
                  if (odf_text_text_only) {
861
 
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_only->current_paragraph_style);
 
845
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_only->m_current_paragraph_style);
862
846
                    if (tab) odf_text_text_only->add_tab();
863
847
                    else odf_text_text_only->add_text (space_type_after_verse);
864
848
                  }
865
849
                  if (odf_text_text_and_note_citations) {
866
 
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->current_paragraph_style);
 
850
                    bool tab = odt_left_align_verse_in_poetry_styles && filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->m_current_paragraph_style);
867
851
                    if (tab) odf_text_text_and_note_citations->add_tab();
868
852
                    else odf_text_text_and_note_citations->add_text (space_type_after_verse);
869
853
                  }
875
859
              // This makes it ready for subsequent use.
876
860
              output_chapter_text_at_first_verse.clear();
877
861
              // Other export formats.
878
 
              if (onlinebible_text) onlinebible_text->newVerse (currentBookIdentifier, currentChapterNumber, convert_to_int (currentVerseNumber));
 
862
              if (onlinebible_text) onlinebible_text->newVerse (m_current_book_identifier, m_current_chapter_number, convert_to_int (currentVerseNumber));
879
863
              if (esword_text) esword_text->newVerse (convert_to_int (currentVerseNumber));
880
864
              if (tbsx_text) {
881
865
                tbsx_text->open_verse(convert_to_int (currentVerseNumber));
937
921
            }
938
922
            case StyleTypePicture:
939
923
            {
940
 
              if (isOpeningMarker) {
941
 
                // Set a flag that the parser is going to be within figure markup.
 
924
              if (is_opening_marker) {
 
925
                // Set a flag that the parser is going to be within figure markup and save the style.
942
926
                is_within_figure_markup = true;
 
927
                figure_marker = marker;
 
928
                // Create the style for the figure because it is used within the ODT generator.
 
929
                create_paragraph_style (style, false);
943
930
                // At the start of the \fig marker, close all text styles that might be open.
944
931
                if (odf_text_standard) odf_text_standard->close_text_style (false, false);
945
932
                if (odf_text_text_only) odf_text_text_only->close_text_style (false, false);
1005
992
              {
1006
993
                case WorListElementSubtypeWordlistGlossaryDictionary:
1007
994
                {
1008
 
                  if (isOpeningMarker) {
 
995
                  if (is_opening_marker) {
1009
996
                    addToWordList (wordListGlossaryDictionary);
1010
997
                  }
1011
998
                  break;
1012
999
                }
1013
1000
                case WorListElementSubtypeHebrewWordlistEntry:
1014
1001
                {
1015
 
                  if (isOpeningMarker) {
 
1002
                  if (is_opening_marker) {
1016
1003
                    addToWordList (hebrewWordList);
1017
1004
                  }
1018
1005
                  break;
1019
1006
                }
1020
1007
                case WorListElementSubtypeGreekWordlistEntry:
1021
1008
                {
1022
 
                  if (isOpeningMarker) {
 
1009
                  if (is_opening_marker) {
1023
1010
                    addToWordList (greekWordList);
1024
1011
                  }
1025
1012
                  break;
1026
1013
                }
1027
1014
                case WorListElementSubtypeSubjectIndexEntry:
1028
1015
                {
1029
 
                  if (isOpeningMarker) {
 
1016
                  if (is_opening_marker) {
1030
1017
                    addToWordList (subjectIndex);
1031
1018
                  }
1032
1019
                  break;
1033
1020
                }
1034
1021
                default:
1035
1022
                {
1036
 
                  if (isOpeningMarker) {
 
1023
                  if (is_opening_marker) {
1037
1024
                    addToFallout (R"(Unknown word list marker \)" + marker, false);
1038
1025
                  }
1039
1026
                  break;
1066
1053
          // Store the name of this image in the object, ready to be copied into place if needed.
1067
1054
          image_sources.push_back(src);
1068
1055
          // Add the image to the various output formats.
1069
 
          if (odf_text_standard) odf_text_standard->add_image(alt, src, caption);
1070
 
          if (odf_text_text_only) odf_text_text_only->add_image(alt, src, caption);
1071
 
          if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_image(alt, src, caption);
1072
 
          if (html_text_standard) html_text_standard->add_image(alt, src, caption);
1073
 
          if (html_text_linked) html_text_linked->add_image(alt, src, caption);
 
1056
          if (odf_text_standard) odf_text_standard->add_image(figure_marker, alt, src, caption);
 
1057
          if (odf_text_text_only) odf_text_text_only->add_image(figure_marker, alt, src, caption);
 
1058
          if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->add_image(figure_marker, alt, src, caption);
 
1059
          if (html_text_standard) html_text_standard->add_image(figure_marker, alt, src, caption);
 
1060
          if (html_text_linked) html_text_linked->add_image(figure_marker, alt, src, caption);
1074
1061
        }
1075
1062
 
1076
1063
        // Treat this content as text.
1080
1067
          // output a tab before any text.
1081
1068
          if (odf_text_standard)
1082
1069
            if (odt_left_align_verse_in_poetry_styles)
1083
 
              if (filter::usfm::is_standard_q_poetry (odf_text_standard->current_paragraph_style))
1084
 
                if (odf_text_standard->current_paragraph_content.empty())
 
1070
              if (filter::usfm::is_standard_q_poetry (odf_text_standard->m_current_paragraph_style))
 
1071
                if (odf_text_standard->m_current_paragraph_content.empty())
1085
1072
                  odf_text_standard->add_tab();
1086
1073
          if (odf_text_text_only)
1087
1074
            if (odt_left_align_verse_in_poetry_styles)
1088
 
              if (filter::usfm::is_standard_q_poetry (odf_text_text_only->current_paragraph_style))
1089
 
                if (odf_text_text_only->current_paragraph_content.empty())
 
1075
              if (filter::usfm::is_standard_q_poetry (odf_text_text_only->m_current_paragraph_style))
 
1076
                if (odf_text_text_only->m_current_paragraph_content.empty())
1090
1077
                  odf_text_text_only->add_tab();
1091
1078
          if (odf_text_text_and_note_citations)
1092
1079
            if (odt_left_align_verse_in_poetry_styles)
1093
 
              if (filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->current_paragraph_style))
1094
 
                if (odf_text_text_and_note_citations->current_paragraph_content.empty())
 
1080
              if (filter::usfm::is_standard_q_poetry (odf_text_text_and_note_citations->m_current_paragraph_style))
 
1081
                if (odf_text_text_and_note_citations->m_current_paragraph_content.empty())
1095
1082
                  odf_text_text_and_note_citations->add_tab();
1096
1083
          // Output text as normal.
1097
1084
          if (odf_text_standard) odf_text_standard->add_text (currentItem);
1168
1155
                  if (odf_text_standard) odf_text_standard->add_note (citation, marker);
1169
1156
                  // Note citation in superscript in the document with text and note citations.
1170
1157
                  if (odf_text_text_and_note_citations) {
1171
 
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->current_text_style;
1172
 
                    odf_text_text_and_note_citations->current_text_style = {"superscript"};
 
1158
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->m_current_text_style;
 
1159
                    odf_text_text_and_note_citations->m_current_text_style = {"superscript"};
1173
1160
                    odf_text_text_and_note_citations->add_text (citation);
1174
 
                    odf_text_text_and_note_citations->current_text_style = currentTextStyles;
 
1161
                    odf_text_text_and_note_citations->m_current_text_style = currentTextStyles;
1175
1162
                  }
1176
1163
                  // Add space if the paragraph has text already.
1177
1164
                  if (odf_text_notes) {
1178
 
                    if (odf_text_notes->current_paragraph_content != "") {
 
1165
                    if (odf_text_notes->m_current_paragraph_content != "") {
1179
1166
                      odf_text_notes->add_text (" ");
1180
1167
                    }
1181
1168
                  }
1204
1191
                  if (odf_text_standard) odf_text_standard->add_note (citation, marker, true);
1205
1192
                  // Note citation in superscript in the document with text and note citations.
1206
1193
                  if (odf_text_text_and_note_citations) {
1207
 
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->current_text_style;
1208
 
                    odf_text_text_and_note_citations->current_text_style = {"superscript"};
 
1194
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->m_current_text_style;
 
1195
                    odf_text_text_and_note_citations->m_current_text_style = {"superscript"};
1209
1196
                    odf_text_text_and_note_citations->add_text (citation);
1210
 
                    odf_text_text_and_note_citations->current_text_style = currentTextStyles;
 
1197
                    odf_text_text_and_note_citations->m_current_text_style = currentTextStyles;
1211
1198
                  }
1212
1199
                  // Open note in the web page.
1213
1200
                  if (html_text_standard) html_text_standard->add_note (citation, standardContentMarkerFootEndNote, true);
1281
1268
                  if (odf_text_standard) odf_text_standard->add_note (citation, marker);
1282
1269
                  // Note citation in superscript in the document with text and note citations.
1283
1270
                  if (odf_text_text_and_note_citations) {
1284
 
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->current_text_style;
1285
 
                    odf_text_text_and_note_citations->current_text_style = {"superscript"};
 
1271
                    vector <string> currentTextStyles = odf_text_text_and_note_citations->m_current_text_style;
 
1272
                    odf_text_text_and_note_citations->m_current_text_style = {"superscript"};
1286
1273
                    odf_text_text_and_note_citations->add_text (citation);
1287
 
                    odf_text_text_and_note_citations->current_text_style = currentTextStyles;
 
1274
                    odf_text_text_and_note_citations->m_current_text_style = currentTextStyles;
1288
1275
                  }
1289
1276
                  // Add a space if the paragraph has text already.
1290
1277
                  if (odf_text_notes) {
1291
 
                    if (odf_text_notes->current_paragraph_content != "") {
 
1278
                    if (odf_text_notes->m_current_paragraph_content != "") {
1292
1279
                      odf_text_notes->add_text (" ");
1293
1280
                    }
1294
1281
                  }
1482
1469
// Returns: The passage text
1483
1470
string Filter_Text::getCurrentPassageText ()
1484
1471
{
1485
 
  return filter_passage_display (currentBookIdentifier, currentChapterNumber, currentVerseNumber);
 
1472
  return filter_passage_display (m_current_book_identifier, m_current_chapter_number, currentVerseNumber);
1486
1473
}
1487
1474
 
1488
1475
 
1546
1533
}
1547
1534
 
1548
1535
 
 
1536
// This function ensures that a certain paragraph style is in the OpenDocument.
 
1537
// $style: The style to use.
 
1538
// $keepWithNext: Whether to keep this paragraph with the next one.
 
1539
void Filter_Text::create_paragraph_style (const Database_Styles_Item & style, bool keepWithNext)
 
1540
{
 
1541
  string marker = style.marker;
 
1542
  if (find (createdStyles.begin(), createdStyles.end(), marker) == createdStyles.end()) {
 
1543
    string fontname = Database_Config_Bible::getExportFont (m_bible);
 
1544
    float fontsize = style.fontsize;
 
1545
    int italic = style.italic;
 
1546
    int bold = style.bold;
 
1547
    int underline = style.underline;
 
1548
    int smallcaps = style.smallcaps;
 
1549
    int alignment = style.justification;
 
1550
    float spacebefore = style.spacebefore;
 
1551
    float spaceafter = style.spaceafter;
 
1552
    float leftmargin = style.leftmargin;
 
1553
    float rightmargin = style.rightmargin;
 
1554
    float firstlineindent = style.firstlineindent;
 
1555
    // Columns are not implemented at present. Reason:
 
1556
    // Copying and pasting sections with columns between documents in LibreOffice failed to work.
 
1557
    // int spancolumns = style.spancolumns;
 
1558
    int dropcaps = 0;
 
1559
    if (odf_text_standard) odf_text_standard->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
 
1560
    if (odf_text_text_only) odf_text_text_only->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
 
1561
    if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
 
1562
    createdStyles.push_back (marker);
 
1563
  }
 
1564
}
 
1565
 
1549
1566
 
1550
1567
// This function ensures that a certain paragraph style is in the OpenDocument,
1551
1568
// and then opens a paragraph with that style.
1553
1570
// $keepWithNext: Whether to keep this paragraph with the next one.
1554
1571
void Filter_Text::new_paragraph (const Database_Styles_Item & style, bool keepWithNext)
1555
1572
{
 
1573
  create_paragraph_style(style, keepWithNext);
1556
1574
  string marker = style.marker;
1557
 
  if (find (createdStyles.begin(), createdStyles.end(), marker) == createdStyles.end()) {
1558
 
    string fontname = Database_Config_Bible::getExportFont (bible);
1559
 
    float fontsize = style.fontsize;
1560
 
    int italic = style.italic;
1561
 
    int bold = style.bold;
1562
 
    int underline = style.underline;
1563
 
    int smallcaps = style.smallcaps;
1564
 
    int alignment = style.justification;
1565
 
    float spacebefore = style.spacebefore;
1566
 
    float spaceafter = style.spaceafter;
1567
 
    float leftmargin = style.leftmargin;
1568
 
    float rightmargin = style.rightmargin;
1569
 
    float firstlineindent = style.firstlineindent;
1570
 
    // Columns are not implemented at present. Reason:
1571
 
    // Copying and pasting sections with columns between documents in LibreOffice failed to work.
1572
 
    // int spancolumns = style.spancolumns;
1573
 
    int dropcaps = 0;
1574
 
    if (odf_text_standard) odf_text_standard->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
1575
 
    if (odf_text_text_only) odf_text_text_only->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
1576
 
    if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->create_paragraph_style (marker, fontname, fontsize, italic, bold, underline, smallcaps, alignment, spacebefore, spaceafter, leftmargin, rightmargin, firstlineindent, keepWithNext, dropcaps);
1577
 
    createdStyles.push_back (marker);
1578
 
  }
1579
1575
  if (odf_text_standard) odf_text_standard->new_paragraph (marker);
1580
1576
  if (odf_text_text_only) odf_text_text_only->new_paragraph (marker);
1581
1577
  if (odf_text_text_and_note_citations) odf_text_text_and_note_citations->new_paragraph (marker);
1594
1590
  // To name a style according to the number of characters to put in drop caps,
1595
1591
  // e.g. a style name like p_c1 or p_c2 or p_c3.
1596
1592
  if (odf_text_standard) {
1597
 
    string combined_style = odf_text_standard->current_paragraph_style + "_" + chapterMarker + convert_to_string (dropCapsLength);
 
1593
    string combined_style = odf_text_standard->m_current_paragraph_style + "_" + chapterMarker + convert_to_string (dropCapsLength);
1598
1594
    if (find (createdStyles.begin(), createdStyles.end(), combined_style) == createdStyles.end()) {
1599
 
      Database_Styles_Item style = styles[odf_text_standard->current_paragraph_style];
1600
 
      string fontname = Database_Config_Bible::getExportFont (bible);
 
1595
      Database_Styles_Item style = styles[odf_text_standard->m_current_paragraph_style];
 
1596
      string fontname = Database_Config_Bible::getExportFont (m_bible);
1601
1597
      float fontsize = style.fontsize;
1602
1598
      int italic = style.italic;
1603
1599
      int bold = style.bold;
1669
1665
void Filter_Text::ensureNoteParagraphStyle (string marker, const Database_Styles_Item & style)
1670
1666
{
1671
1667
  if (find (createdStyles.begin(), createdStyles.end(), marker) == createdStyles.end()) {
1672
 
    string fontname = Database_Config_Bible::getExportFont (bible);
 
1668
    string fontname = Database_Config_Bible::getExportFont (m_bible);
1673
1669
    float fontsize = style.fontsize;
1674
1670
    int italic = style.italic;
1675
1671
    int bold = style.bold;
1717
1713
}
1718
1714
 
1719
1715
 
1720
 
void Filter_Text::storeVersesParagraphs ()
 
1716
void Filter_Text::store_verses_paragraphs ()
1721
1717
{
1722
1718
  if (!actual_verses_paragraph.empty ()) {
1723
1719
    verses_paragraphs.push_back (actual_verses_paragraph);