/// ------------------------------------------------------------------------------------ /// <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; }
/// ------------------------------------------------------------------------------------- /// <summary> /// Create all of the ScrBookRef objects for each book of Scripture /// </summary> /// <param name="progressDlg">Progress dialog so the user can cancel</param> /// ------------------------------------------------------------------------------------- protected void CreateScrBookRefs(IAdvInd4 progressDlg) { IScrRefSystem scr = m_cache.ScriptureReferenceSystem; // If there are books existing, then delete them first. for (int i = scr.BooksOS.Count - 1; i >= 0; i--) { scr.BooksOS.RemoveAt(i); } XmlDocument doc = new XmlDocument(); doc.Load(DirectoryFinder.FWCodeDirectory + @"\Translation Editor\ScrBookRef.xml"); ILgWritingSystemFactory wsf = m_cache.LanguageWritingSystemFactoryAccessor; //Select and display the value of all the ISBN attributes. XmlNodeList tagList = doc.SelectNodes("/ScrBookRef/writingsystem"); progressDlg.SetRange(0, tagList.Count * ScrReference.LastBook); progressDlg.Position = 0; progressDlg.Title = TeResourceHelper.GetResourceString("kstidCreatingBookNames"); foreach (XmlNode writingSystem in tagList) { XmlAttributeCollection attributes = writingSystem.Attributes; string sLocale = attributes.GetNamedItem("iculocale").Value; int ws = m_cache.LanguageEncodings.GetWsFromIcuLocale(sLocale); if (ws == 0) { // It is possible that the XML file contains more languages than the // database. If so, just ignore this writing system. continue; } short iBook = 0; XmlNodeList WSBooks = writingSystem.SelectNodes("book"); foreach (XmlNode book in WSBooks) { XmlAttributeCollection bookAttributes = book.Attributes; string sSilBookId = bookAttributes.GetNamedItem("SILBookId").Value; Debug.Assert(sSilBookId != null); // Make sure books are coming in canonical order. Debug.Assert(ScrReference.BookToNumber(sSilBookId) == iBook + 1); string sName = bookAttributes.GetNamedItem("Name").Value; string sAbbrev = bookAttributes.GetNamedItem("Abbreviation").Value; string sAltName = bookAttributes.GetNamedItem("AlternateName").Value; progressDlg.Message = string.Format( TeResourceHelper.GetResourceString("kstidCreatingBookNamesStatusMsg"), sName); progressDlg.Step(0); // check for the book id ScrBookRef bookRef = null; if (scr.BooksOS.Count > iBook) { bookRef = (ScrBookRef)scr.BooksOS[iBook]; Debug.Assert(bookRef != null); } else { // add this book to the list bookRef = new ScrBookRef(); scr.BooksOS.Append(bookRef); } if (sName != null) { bookRef.BookName.SetAlternative(sName, ws); } if (sAbbrev != null) { bookRef.BookAbbrev.SetAlternative(sAbbrev, ws); } if (sAltName != null) { bookRef.BookNameAlt.SetAlternative(sAltName, ws); } iBook++; } } }