Logo Search packages:      
Sourcecode: bibledit version File versions  Download package

editornote.cpp

/*
** Copyright (C) 2003-2006 Teus Benschop.
**  
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**  
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**  
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**  
*/


#include "libraries.h"
#include "utilities.h"
#include "editornote.h"
#include "usfmtools.h"
#include "constants.h"
#include "gwrappers.h"


EditorNote::EditorNote (const Usfm& usfm)
// Stores the properties for all the footnote related styles.
{
  // Store and initialize variables.
  NoteNumberingType footnote_numbering_type = nntNumerical;
  NoteNumberingType endnote_numbering_type = nntNumerical;
  NoteNumberingType xref_numbering_type = nntAlphabetical;  
  footnote_numbering_restart = nnrtChapter;
  endnote_numbering_restart = nnrtNever;
  xref_numbering_restart = nnrtChapter;
  ustring footnote_numbering_user_sequence;
  ustring endnote_numbering_user_sequence;
  ustring xref_numbering_user_sequence;
  
  // Go through all the styles.
  for (unsigned int i = 0; i < usfm.styles.size(); i++) {
    if (usfm.styles[i].type == stFootEndNote) {
      // Check subtype.
      FootEndNoteType footnotetype = (FootEndNoteType) usfm.styles[i].subtype;
      switch (footnotetype) {
        case fentFootnote:
        {
          // Store data.
          footnote_opener = usfm_get_full_opening_marker (usfm.styles[i].marker);
          footnote_closer = usfm_get_full_closing_marker (usfm.styles[i].marker);
          footnote_numbering_type = (NoteNumberingType) usfm.styles[i].userint1;
          footnote_numbering_restart = (NoteNumberingRestartType) usfm.styles[i].userint2;
          if (footnote_numbering_restart == nnrtPage) {
            footnote_numbering_restart = nnrtChapter;
          }
          footnote_numbering_user_sequence = usfm.styles[i].userstring1;
          break;
        }
        case fentEndnote:
        {
          // Store data.
          endnote_opener = usfm_get_full_opening_marker (usfm.styles[i].marker);
          endnote_closer = usfm_get_full_closing_marker (usfm.styles[i].marker);
          endnote_numbering_type = (NoteNumberingType) usfm.styles[i].userint1;
          endnote_numbering_restart = (NoteNumberingRestartType) usfm.styles[i].userint2;
          // Restarting notes per page not supported in SWORD as there are no pages there.
          if (endnote_numbering_restart == nnrtPage) {
            endnote_numbering_restart = nnrtChapter;
          }
          endnote_numbering_user_sequence = usfm.styles[i].userstring1;
          break;
        }
        case fentStandardContent:
        {
          // Standard content.
          standardparagraph_marker_open = usfm_get_full_opening_marker (usfm.styles[i].marker);
          standardparagraph_marker_close = usfm_get_full_closing_marker (usfm.styles[i].marker);
          footnote_markers.insert (usfm.styles[i].marker);
          break;
        }
        case fentContent:
        case fentContentWithEndmarker:
        {
          // Store data for the footnote body.
          content_marker.push_back (usfm_get_full_opening_marker (usfm.styles[i].marker));
          footnote_markers.insert (usfm.styles[i].marker);
          break;
        }
        case fentParagraph:
        {
          extraparagraph_marker_open = usfm_get_full_opening_marker (usfm.styles[i].marker);
          extraparagraph_marker_close = usfm_get_full_closing_marker (usfm.styles[i].marker);
          footnote_markers.insert (usfm.styles[i].marker);
          break;
        }
      }
    }
    if (usfm.styles[i].type == stCrossreference) {
      // Check subtype.
      CrossreferenceType xreftype = (CrossreferenceType) usfm.styles[i].subtype;
      switch (xreftype) {
        case ctCrossreference:
        {
          // Store data for the markers and the anchor.
          xref_opener = usfm_get_full_opening_marker (usfm.styles[i].marker);
          xref_closer = usfm_get_full_closing_marker (usfm.styles[i].marker);
          xref_numbering_type = (NoteNumberingType) usfm.styles[i].userint1;
          xref_numbering_restart = (NoteNumberingRestartType) usfm.styles[i].userint2;
          if (xref_numbering_restart == nnrtPage) {
            xref_numbering_restart = nnrtChapter;
          }
          xref_numbering_user_sequence = usfm.styles[i].userstring1;
          break;
        }
        case ctStandardContent:
        {
          // Standard content.
          standardparagraph_marker_open = usfm_get_full_opening_marker (usfm.styles[i].marker);
          standardparagraph_marker_close = usfm_get_full_closing_marker (usfm.styles[i].marker);
          footnote_markers.insert (usfm.styles[i].marker);
          break;
        }
        case ctContent:
        case ctContentWithEndmarker:
        {
          // Store data for the footnote body.
          content_marker.push_back (usfm_get_full_opening_marker (usfm.styles[i].marker));
          footnote_markers.insert (usfm.styles[i].marker);
          break;
        }
      }
    }
  }
  // Ensure that both of the paragraph styles are there.
  if (standardparagraph_marker_open.empty()) {
    standardparagraph_marker_open = usfm_get_full_opening_marker ("ft");
    standardparagraph_marker_close = usfm_get_full_closing_marker ("ft");
  }
  if (extraparagraph_marker_open.empty()) {
    extraparagraph_marker_open = usfm_get_full_opening_marker ("fp");
    extraparagraph_marker_close = usfm_get_full_closing_marker ("fp");
  }
  // Create note caller objects.
  footnotecaller = new NoteCaller (footnote_numbering_type, footnote_numbering_user_sequence, false);
  endnotecaller = new NoteCaller (endnote_numbering_type, endnote_numbering_user_sequence, false);
  xrefcaller = new NoteCaller (xref_numbering_type, xref_numbering_user_sequence, false);
}


EditorNote::~EditorNote ()
{
  delete footnotecaller;
  delete endnotecaller;
  delete xrefcaller;
}


void EditorNote::extract (ustring& line)
{
  // Clear containers.
  types.clear();
  positions.clear();
  lengths.clear();
  openers.clear();
  callers.clear();
  rendered_callers.clear();
  texts.clear();
  closers.clear();
  // Deal with the three types we recognize.
  extract_internal (line);
}


void EditorNote::extract_internal (ustring& line)
// Extract and store all note related content.
{
  // Variables.
  size_t opening_position;
  EditorObjectType type;
  ustring opener;
  ustring closer;
  NoteCaller * caller;
  
  // Look for notes, but only deal with them if they have the endmarker too.
  opening_position = find_opener (line, 0, type, opener, closer, caller);
  while (opening_position != string::npos) {

    // Look for the endmarker.
    size_t closing_position;
    closing_position = line.find (closer, opening_position);    
    if (closing_position == string::npos) {
      gw_warning ("Note: missing endmarker");
      return;
    }

    // Get this note.
    ustring note;
    note = line.substr (opening_position + opener.length(), closing_position - opening_position - closer.length());
    // Remove it from the line.
    line.erase (opening_position, note.length() + opener.length() + closer.length());

    // Handle the footnote caller.    
    ustring callercode;
    ustring callertext;
    if (note.length() > 0) {
      callercode = note.substr (0, 1);
      callercode = trim (callercode);
      callertext = callercode;
      if (callercode == "+") {
        callertext = caller->get_caller();
      } else if (callercode == "-") {
        callertext = "*";
      }
      note.erase (0, 1);
      note = trim (note);
    }

    // Insert the caller text into the line. This is to get the positions right.
    line.insert (opening_position, callertext);
     
    // Store everything.
    types.push_back (type);
    positions.push_back (opening_position);
    lengths.push_back (closing_position - opening_position + closer.length());
    openers.push_back (opener);
    callers.push_back (callercode);
    rendered_callers.push_back (callertext);
    texts.push_back (note);
    closers.push_back (closer);

    // Search for another note.
    opening_position = find_opener (line, ++opening_position, type, opener, closer, caller);
  }
}


size_t EditorNote::find_opener (ustring& line, size_t searchfrom, EditorObjectType& type, 
                                ustring& opener, ustring& closer, NoteCaller *& notecaller)
{
  // Look for any of the possible opening markers.
  size_t footnote_position = line.find (footnote_opener, searchfrom);
  size_t endnote_position = line.find (endnote_opener, searchfrom);
  size_t xref_position = line.find (xref_opener, searchfrom);
  // Take the first of them.
  size_t smallest_position = string::npos;
  if (footnote_position < smallest_position)
    smallest_position = footnote_position;
  if (endnote_position < smallest_position)
    smallest_position = endnote_position;
  if (xref_position < smallest_position)
    smallest_position = xref_position;
  // Set values depending on which note we found first.
  if (smallest_position == footnote_position) {
    type = eotFootnote;
    opener = footnote_opener;
    closer = footnote_closer;
    notecaller = footnotecaller;
  }
  if (smallest_position == endnote_position) {
    type = eotEndnote;
    opener = endnote_opener;
    closer = endnote_closer;
    notecaller = endnotecaller;
  }
  if (smallest_position == xref_position) {
    type = eotCrossreference;
    opener = xref_opener;
    closer = xref_closer;
    notecaller = xrefcaller;
  }
  // Return position found.
  return smallest_position;
}

Generated by  Doxygen 1.6.0   Back to index