Example #1
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Read the file to build mappings of the markers found
        /// </summary>
        /// ------------------------------------------------------------------------------------
        protected void GetMappingsFromStream(TextReader reader)
        {
            string lineIn;

            int chapter   = -1;
            int book      = -1;
            int lineCount = 0;

            // book and chapter strings for reporting info in exceptions
            string sBookId  = null;
            string sChapter = null;
            string sVerse   = null;

            // Keep track of the first reference in the file
            int firstBook    = -1;
            int firstChapter = -1;
            int firstVerse   = -1;

            ReferenceRange currentRange = null;
            string         marker;
            string         lineText;
            string         nextLineText = null;     // used for read-ahead for \fig line when doing strict scanning

            while ((lineIn = reader.ReadLine()) != null)
            {
                lineCount++;
                while (GetNextMarkerFromData(lineIn, out marker, out lineText))
                {
                    // Make sure the marker is valid
                    if (!IsValidMarker(marker))
                    {
                        throw new ScriptureUtilsException(SUE_ErrorCode.InvalidCharacterInMarker,
                                                          FileName, lineCount, lineIn, sBookId, sChapter, sVerse);
                    }

                    ImportMappingInfo markerMapping = GetOrCreateMarkerMapping(ref marker);

                    if (marker == ScrMappingList.MarkerBook)
                    {
                        sBookId = lineText.TrimStart().ToUpperInvariant();

                        // save the book number in the list for this file
                        book = ScrReference.BookToNumber(sBookId);
                        if (book <= 0)
                        {
                            throw new ScriptureUtilsException(SUE_ErrorCode.InvalidBookID, FileName,
                                                              lineCount, lineIn, sBookId, null, null);
                        }
                        sBookId = ScrReference.NumberToBookCode(book);

                        // Make a new reference range with the book id and
                        // start it out with chapter range of 0-0.
                        AddRangeToList(currentRange);
                        currentRange = new ReferenceRange(book, 0, 0);

                        // If this is the first book, remember it
                        if (firstBook == -1)
                        {
                            firstBook = book;
                        }
                        m_booksInFile.Add(book);
                        chapter = -1;
                    }
                    else
                    {
                        // make sure that a book has been started before seeing any non-excluded markers
                        // This error is a "strict" error because files can be added by a user before there
                        // is a chance to exclude markers in the mappings. When the file is added from the settings
                        // for import, then strict checking will be on.
                        if (book == -1 && m_doStrictFileChecking)
                        {
                            // if the marker is not excluded then throw an error
                            if (markerMapping != null && !markerMapping.IsExcluded)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.UnexcludedDataBeforeIdLine,
                                                                  FileName, lineCount, lineIn, null, null, null);
                            }
                        }

                        if (marker == ScrMappingList.MarkerChapter)
                        {
                            // If there is no book, then throw an error since chapter numbers
                            // are not valid without a book
                            if (book == -1)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.ChapterWithNoBook,
                                                                  FileName, lineCount, lineIn, null, null, null);
                            }
                            try
                            {
                                sChapter = lineText;
                                chapter  = ScrReference.ChapterToInt(sChapter);

                                // save the chapter number as the last chapter and possibly the first
                                // chapter number in the range.
                                if (currentRange.StartChapter == 0)
                                {
                                    currentRange.StartChapter = chapter;
                                }
                                currentRange.EndChapter = chapter;
                            }
                            catch (ArgumentException)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.InvalidChapterNumber,
                                                                  FileName, lineCount, lineIn, sBookId, sChapter, null);
                            }
                            // If this is the first chapter, remember it
                            if (firstChapter == -1)
                            {
                                firstChapter = chapter;
                            }
                        }

                        else if (marker == ScrMappingList.MarkerVerse)
                        {
                            // If a verse is seen without a book, throw an exception
                            if (book == -1)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.VerseWithNoBook,
                                                                  FileName, lineCount, lineIn, sBookId, null, lineText);
                            }

                            BCVRef firstRef = new BCVRef(book, chapter, 0);
                            BCVRef lastRef  = new BCVRef(book, chapter, 0);

                            // check for an invalid verse number
                            if (!BCVRef.VerseToScrRef(lineText, ref firstRef, ref lastRef) ||
                                firstRef.Verse == 0 || firstRef.Verse > lastRef.Verse)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.InvalidVerseNumber,
                                                                  FileName, lineCount, lineIn, sBookId, sChapter, lineText);
                            }

                            // If a chapter number has not been seen yet, then throw an exception
                            sVerse = firstRef.Verse.ToString();
                            if (chapter == -1 && !SingleChapterBook(book))
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.MissingChapterNumber,
                                                                  FileName, lineCount, lineIn, sBookId, null, sVerse);
                            }

                            // If this is the first verse, remember it
                            if (firstVerse == -1)
                            {
                                firstVerse = firstRef.Verse;
                            }
                        }
                        else if (!markerMapping.IsExcluded && m_doStrictFileChecking &&
                                 markerMapping.MappingTarget == MappingTargetType.Figure)
                        {
                            // First, we need to consider whether any following lines also need
                            // to be read in, since the Figure parameters could be split across
                            // lines. (TE-7669)
                            Debug.Assert(nextLineText == null);
                            int    cExtraLinesRead = 0;
                            string sTempMarker, sTempLineText;
                            if (!GetNextMarkerFromData(lineText, out sTempMarker, out sTempLineText))
                            {
                                while ((nextLineText = reader.ReadLine()) != null)
                                {
                                    cExtraLinesRead++;
                                    if (GetNextMarkerFromData(nextLineText, out sTempMarker, out sTempLineText))
                                    {
                                        // Normally, we want to break the line right before the first marker.
                                        int ichMarkerPos = nextLineText.IndexOf(sTempMarker);
                                        // But if it's a \fig*, break after the marker.
                                        if (sTempMarker == markerMapping.EndMarker)
                                        {
                                            ichMarkerPos += sTempMarker.Length;
                                        }
                                        lineText    += " " + nextLineText.Substring(0, ichMarkerPos);
                                        nextLineText = nextLineText.Substring(ichMarkerPos);
                                        break;
                                    }
                                    else
                                    {
                                        lineText += " " + nextLineText;
                                    }
                                }
                            }

                            string figureParams    = lineText;
                            int    endMarkerLength = 0;
                            // Validate the tokens for a mapping target (only in strict checking)
                            if (!String.IsNullOrEmpty(markerMapping.EndMarker))
                            {
                                endMarkerLength = markerMapping.EndMarker.Length;
                                int ichEnd = figureParams.IndexOf(markerMapping.EndMarker);
                                if (ichEnd >= 0)
                                {
                                    figureParams = figureParams.Substring(0, ichEnd);
                                }
                                else
                                {
                                    endMarkerLength = 0;                                     // end marker is optional and not present
                                }
                            }
                            string[] tokens = figureParams.Split('|');
                            if (tokens.Length < 6)
                            {
                                throw new ScriptureUtilsException(SUE_ErrorCode.BadFigure, FileName,
                                                                  lineCount, lineIn, sBookId, sChapter, sVerse);
                            }
                            lineText   = lineText.Substring(figureParams.Length + endMarkerLength);
                            lineCount += cExtraLinesRead;
                        }
                    }
                    // Mark this mapping as "in-use" because it was found in the scanned file
                    markerMapping.SetIsInUse(m_domain, m_wsId, m_noteType, true);

                    if (m_scanInlineBackslashMarkers)
                    {
                        lineIn = lineText;
                    }
                    else
                    {
                        lineIn       = nextLineText;
                        nextLineText = null;
                        if (lineIn == null)
                        {
                            break;
                        }
                    }
                    if (string.IsNullOrEmpty(lineIn) && !string.IsNullOrEmpty(nextLineText))
                    {
                        lineIn       = nextLineText;
                        nextLineText = null;
                    }
                }
            }
            // Add the last range to the list
            AddRangeToList(currentRange);

            // If no books were found in the file then throw an exception
            if (book == -1)
            {
                throw new ScriptureUtilsException(SUE_ErrorCode.MissingBook,
                                                  FileName, lineCount, null, null, null, null);
            }


            // If no chapters were found then throw an exception
            if (chapter == -1 && !SingleChapterBook(book))
            {
                throw new ScriptureUtilsException(SUE_ErrorCode.NoChapterNumber,
                                                  FileName, lineCount, null, sBookId, null, null);
            }

            // Store the first reference for the file
            m_startRef.Book    = firstBook;
            m_startRef.Chapter = firstChapter == -1 ? 1 : firstChapter;
            m_startRef.Verse   = firstVerse == -1 ? 1 : firstVerse;
        }
        public bool LoadProjectMappings(string project, ScrMappingList mappingList, ImportDomain domain)
        {
            // If the new project ID is null, then do not load mappings.
            if (project == null)
            {
                return(false);
            }

            // Load the tags from the paratext project and create mappings for them.
            ScrText scParatextText;

            try
            {
                // REVIEW (EberhardB): I'm not sure if ScrTextCollection.Get() returns a
                // reference to a ScrText or a new object (in which case we would have to
                // call Dispose() on it)
                scParatextText = ScrTextCollection.Get(project);
            }
            catch (Exception ex)
            {
                Logger.WriteError(ex);
                return(false);
            }

            mappingList.ResetInUseFlags(domain);
            try
            {
                foreach (ScrTag tag in scParatextText.DefaultStylesheet.Tags)
                {
                    if (tag == null)
                    {
                        break;
                    }
                    string marker    = @"\" + tag.Marker;
                    string endMarker = string.Empty;
                    if (!String.IsNullOrEmpty(tag.Endmarker))
                    {
                        endMarker = @"\" + tag.Endmarker;
                    }

                    // When the nth marker has an end marker, the nth + 1 marker will be
                    // that end marker. Therefore, we have to skip those "end style" markers.
                    if (tag.StyleType == ScrStyleType.scEndStyle)
                    {
                        continue;
                    }

                    // Create a new mapping for this marker.
                    mappingList.AddDefaultMappingIfNeeded(marker, endMarker, domain, false, false);
                }
                ScrParser parser = scParatextText.Parser();
                foreach (int bookNum in scParatextText.BooksPresentSet.SelectedBookNumbers())
                {
                    foreach (UsfmToken token in parser.GetUsfmTokens(new VerseRef(bookNum, 0, 0), false, true))
                    {
                        if (token.Marker == null)
                        {
                            continue;                             // Tokens alternate between text and marker types
                        }
                        ImportMappingInfo mapping = mappingList[@"\" + token.Marker];
                        if (mapping != null)
                        {
                            mapping.SetIsInUse(domain, true);
                        }

                        // ENHANCE (TE-4408): Consider Detecting markers that occur in the data but are missing
                        // from the STY file. How can we write a test for this?
                        //else if (ScrImportFileInfo.IsValidMarker(sMarker))
                        //{
                        //    mappingList.AddDefaultMappingIfNeeded(sMarker,domain, false, true);
                        //}
                        //else
                        //{
                        //    throw new ScriptureUtilsException(SUE_ErrorCode.InvalidCharacterInMarker, null, 0,
                        //        sMarker + sText, new ScrReference(scParatextTextSegment.FirstReference.BBCCCVVV));
                        //}
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.WriteError(ex);
                return(false);
            }
            return(true);
        }