/// ------------------------------------------------------------------------------------ /// <summary> /// Sets the enumerator to its initial position, which is before the first element in /// the collection. /// </summary> /// <exception cref="T:System.InvalidOperationException">The collection was modified /// after the enumerator was created. </exception> /// ------------------------------------------------------------------------------------ public void Reset() { m_internalToken = new ScrCheckingToken(); m_outerText = null; if (m_chapterNum == 0) { m_currentScrText = new TokenizableText(m_book.TitleOA, TextType.Other); m_currentSection = null; m_iCurrentSection = -1; m_internalToken.m_startRef = m_internalToken.m_endRef = new ScrReference(m_book.CanonicalNum, 1, 0, m_scr.Versification); m_foundStart = true; } else { // Set to the first token for the requested chapter CurrentSectionIndex = m_book.FindSectionForChapter(m_chapterNum); if (ScrReference.GetChapterFromBcv(m_currentSection.VerseRefStart) != m_chapterNum) { m_currentScrText = new TokenizableText(m_currentSection.ContentOA, TextType.Verse); m_foundStart = false; } else { m_foundStart = true; } } }
/// ------------------------------------------------------------------------------------ /// <summary> /// Create an annotation in response to an error returned by a check. /// The check calls this delegate whenever an error is found. /// </summary> /// <param name="args">Information about the potential inconsistency being reported</param> /// ------------------------------------------------------------------------------------ public void RecordError(RecordErrorEventArgs args) { ScrCheckingToken firstToken = args.Tts.FirstToken as ScrCheckingToken; ScrCheckingToken lastToken = args.Tts.LastToken as ScrCheckingToken; Debug.Assert(firstToken != null); Debug.Assert(lastToken != null); Debug.Assert(firstToken.Object == lastToken.Object); int offset = args.Tts.Offset; int length = args.Tts.Length; Guid checkId = args.CheckId; string formattedMsg = args.Tts.Message; // If the token is for a missing reference, then replace the token's // reference range with the missing reference range. if (args.Tts.MissingStartRef != null && !args.Tts.MissingStartRef.IsEmpty) { firstToken.m_startRef = new BCVRef(firstToken.MissingStartRef); firstToken.m_endRef = new BCVRef(firstToken.MissingEndRef != null ? firstToken.m_missingEndRef : firstToken.m_startRef); } int bookNum = firstToken.StartRef.Book; string citedText = args.Tts.Text; IScrBookAnnotations annotations = (IScrBookAnnotations)m_scr.BookAnnotationsOS[bookNum - 1]; // key for the error with the same cited text and message at a particular reference. string errorLocKey = firstToken.StartRef.AsString + lastToken.EndRef.AsString + citedText + formattedMsg; // key for an error with the same cited text and message. string errorKey = checkId.ToString() + citedText + formattedMsg; if (CheckForPreviousInconsistency(firstToken, lastToken, citedText, offset, length, checkId, errorLocKey, errorKey)) { return; } // NOTE: A maxIdenticalErrors value of -1 indicates that there is no maximum set. int maxIdenticalErrors = GetMaxIdenticalErrors(checkId); int errorCount = m_errorCounts.GetValue(errorKey); // Check the number of times this same error has already been reported. // If the maximum allowed number of identical errors already has been reached then // we don't want to report the error as usual. if (errorCount == maxIdenticalErrors) { formattedMsg = GetExceededErrorMsg(checkId); } else if (errorCount > maxIdenticalErrors && maxIdenticalErrors > -1) { // We have exceeded the maximum allowed for this error, so don't write out an annotation. return; } m_errorCounts.IncrementError(errorKey); AddErrorAnnotation(citedText, offset, length, checkId, firstToken, lastToken, formattedMsg); m_bookChecksFailed[bookNum][checkId] = ScrCheckRunResult.Inconsistencies; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Performs tasks associated with freeing, releasing, or resetting unmanaged resources. /// </summary> /// ------------------------------------------------------------------------------------ protected virtual void Dispose(bool fDisposing) { System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****** Missing Dispose() call for " + GetType().Name + ". ****** "); if (fDisposing && !IsDisposed) { // dispose managed and unmanaged objects } m_book = null; m_currentSection = null; m_internalToken = null; m_outerText = null; m_currentScrText = null; IsDisposed = true; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds the error annotation to the database. /// </summary> /// <param name="citedText">The cited text.</param> /// <param name="offset">The offset.</param> /// <param name="length">The length.</param> /// <param name="checkId">The Scripture error checking id.</param> /// <param name="firstToken">The first token.</param> /// <param name="lastToken">The last token.</param> /// <param name="formattedMsg">The formatted error message.</param> /// ------------------------------------------------------------------------------------ private void AddErrorAnnotation(string citedText, int offset, int length, Guid checkId, ScrCheckingToken firstToken, ScrCheckingToken lastToken, string formattedMsg) { IScrBookAnnotations annotations = (IScrBookAnnotations)m_scr.BookAnnotationsOS[firstToken.StartRef.Book - 1]; StTxtParaBldr quote = SetCitedText(citedText, firstToken.Ws); StTxtParaBldr discussion = SetErrorMessage(formattedMsg); IScrScriptureNote note = annotations.InsertErrorAnnotation(firstToken.StartRef, lastToken.EndRef, firstToken.Object, lastToken.Object, checkId, quote, discussion); note.BeginOffset = firstToken.ParaOffset + offset; note.EndOffset = note.BeginOffset + length; note.Flid = firstToken.Flid; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Copies this instance. /// </summary> /// <returns>A copy of this token</returns> /// ------------------------------------------------------------------------------------ public ScrCheckingToken Copy() { ScrCheckingToken newToken = new ScrCheckingToken(); newToken.m_endRef = new BCVRef(m_endRef); newToken.m_flid = m_flid; newToken.m_fNoteStart = m_fNoteStart; newToken.m_fParagraphStart = m_fParagraphStart; newToken.m_icuLocale = m_icuLocale; newToken.m_object = m_object; newToken.m_startRef = new BCVRef(m_startRef); newToken.m_sText = m_sText; newToken.m_paraStyleName = m_paraStyleName; newToken.m_charStyleName = m_charStyleName; newToken.m_textType = m_textType; newToken.m_ws = m_ws; newToken.m_paraOffset = m_paraOffset; newToken.m_scrRefString = m_scrRefString; newToken.m_missingStartRef = m_missingStartRef; newToken.m_missingEndRef = m_missingEndRef; return newToken; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Copies this instance. /// </summary> /// <returns>A copy of this token</returns> /// ------------------------------------------------------------------------------------ public ScrCheckingToken Copy() { ScrCheckingToken newToken = new ScrCheckingToken(); newToken.m_endRef = new BCVRef(m_endRef); newToken.m_flid = m_flid; newToken.m_fNoteStart = m_fNoteStart; newToken.m_fParagraphStart = m_fParagraphStart; newToken.m_icuLocale = m_icuLocale; newToken.m_object = m_object; newToken.m_startRef = new BCVRef(m_startRef); newToken.m_sText = m_sText; newToken.m_paraStyleName = m_paraStyleName; newToken.m_charStyleName = m_charStyleName; newToken.m_textType = m_textType; newToken.m_ws = m_ws; newToken.m_paraOffset = m_paraOffset; newToken.m_scrRefString = m_scrRefString; newToken.m_missingStartRef = m_missingStartRef; newToken.m_missingEndRef = m_missingEndRef; return(newToken); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Checks whether or not there is a checking error result (i.e. ScrScriptureNote) for /// the specified check ID, reference, cited text and error message. If one does exist, /// then we must do some updating. /// </summary> /// <param name="firstToken">The first token.</param> /// <param name="lastToken">The last token.</param> /// <param name="citedText">The cited text.</param> /// <param name="offset">The character offset of the start of the inconsistency in the /// .</param> /// <param name="length">The length.</param> /// <param name="checkId">The check id.</param> /// <param name="errorLocKey">The error location key, that includes both the beginning /// and ending reference of the error as well as the cited text and error message.</param> /// <param name="errorKey">The error key which includes the check id, the cited text /// and the error message.</param> /// <returns></returns> /// ------------------------------------------------------------------------------------ private bool CheckForPreviousInconsistency(ScrCheckingToken firstToken, ScrCheckingToken lastToken, string citedText, int offset, int length, Guid checkId, string errorLocKey, string errorKey) { int bookNum = firstToken.StartRef.Book; List <IScrScriptureNote> errors; if (m_pendingCheckErrors == null || !m_pendingCheckErrors[bookNum][checkId].TryGetValue(errorLocKey, out errors)) { // We don't have a previous inconsistency, so nothing needs to be updated. return(false); } // We have previously created an identical annotation (same error, same reference), // so we need to check if there is not already an inconsistency logged for the current // book and check... if (m_bookChecksFailed[bookNum][checkId] != ScrCheckRunResult.Inconsistencies) { // If the error is closed, then the book and check are marked as having // at least one ignored inconsistency. Otherwise, the book and check are marked // as having at least one inconsistency. m_bookChecksFailed[bookNum][checkId] = (errors[0].ResolutionStatus == NoteStatus.Closed ? ScrCheckRunResult.IgnoredInconsistencies : ScrCheckRunResult.Inconsistencies); } int maxIdenticalErrors = GetMaxIdenticalErrors(checkId); // If the error isn't ignored... if (errors[0].ResolutionStatus != NoteStatus.Closed) { // If the maximum number of identical errors was just exceeded for this // Scripture check. Create a new ScrScriptureNote to indicate this. if (m_errorCounts.GetValue(errorKey) == maxIdenticalErrors) { AddErrorAnnotation(citedText, offset, length, checkId, firstToken, lastToken, GetExceededErrorMsg(checkId)); } m_errorCounts.IncrementError(errorKey); } // This is a duplicate error message and not beyond the maximum set for this check, // so we want to remove the annotation from our list of annotations to delete. // We will use this annotation instead of the one that was generated from an editorial // check. if (m_errorCounts.GetValue(errorKey) <= maxIdenticalErrors || maxIdenticalErrors == -1) { errors[0].BeginOffset = firstToken.ParaOffset + offset; errors[0].EndOffset = errors[0].BeginOffset + length; errors[0].BeginObjectRA = firstToken.m_object; errors[0].EndObjectRA = firstToken.m_object; errors.RemoveAt(0); if (errors.Count == 0) { m_pendingCheckErrors[bookNum][checkId].Remove(errorLocKey); } } return(true); }
public void GetTokenSubstrings_ValidatorThatRemovesSomeResults() { using (var ctrl = new CharContextCtrl()) { ctrl.Initialize(Cache, Cache.ServiceLocator.WritingSystems, null, null, null, null); ctrl.ListValidator = RemoveFirstAndLastSubString; var tokens = new List<ITextToken>(); ITextToken token = new ScrCheckingToken(); ReflectionHelper.SetField(token, "m_sText", "Mom. Dad! Brother(Sister)"); tokens.Add(token); var inventory = new DummyScrInventory { m_references = new List<TextTokenSubstring> { new TextTokenSubstring(token, 3, 2), new TextTokenSubstring(token, 8, 2), new TextTokenSubstring(token, 17, 1), new TextTokenSubstring(token, 24, 1) } }; var validatedList = (List<TextTokenSubstring>)ReflectionHelper.GetResult(ctrl, "GetTokenSubstrings", inventory, tokens); Assert.AreEqual(2, validatedList.Count); Assert.AreEqual("! ", validatedList[0].Text); Assert.AreEqual("(", validatedList[1].Text); } }
public void GetTokenSubstrings_NoValidator() { using (var ctrl = new CharContextCtrl()) { ctrl.Initialize(Cache, Cache.ServiceLocator.WritingSystems, null, null, null, null); var tokens = new List<ITextToken>(); ITextToken token = new ScrCheckingToken(); ReflectionHelper.SetField(token, "m_sText", "Mom. Dad!"); tokens.Add(token); var inventory = new DummyScrInventory { m_references = new List<TextTokenSubstring> { new TextTokenSubstring(token, 3, 2) } }; var validatedList = (List<TextTokenSubstring>)ReflectionHelper.GetResult(ctrl, "GetTokenSubstrings", inventory, tokens); Assert.AreEqual(1, validatedList.Count); Assert.AreEqual(". ", validatedList[0].Text); } }
internal DummyError(ScrCheckingToken token, int ichStart, int length, string sMessage) { m_token = token; m_ichStart = ichStart; m_length = length; m_sMessage = sMessage; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; false if the /// enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException">The collection was modified /// after the enumerator was created. </exception> /// ------------------------------------------------------------------------------------ public bool MoveNext() { if (m_currentScrText == null) { return(false); } while (++m_currentScrText.m_iRun < m_currentScrText.m_paraTss.RunCount) { m_internalToken.m_fParagraphStart = (m_currentScrText.m_iRun == 0); ITsTextProps runProps = m_currentScrText.m_paraTss.get_Properties(m_currentScrText.m_iRun); string charStyleName = runProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle); m_internalToken.m_sText = m_currentScrText.m_paraTss.get_RunText(m_currentScrText.m_iRun); m_internalToken.m_paraOffset = m_currentScrText.m_paraTss.get_MinOfRun(m_currentScrText.m_iRun); int var; int ws = runProps.GetIntPropValues((int)FwTextPropType.ktptWs, out var); m_internalToken.m_icuLocale = GetLocale(ws); m_internalToken.Ws = ws; switch (runProps.GetStrPropValue((int)FwTextPropType.ktptNamedStyle)) { case ScrStyleNames.VerseNumber: if (!m_foundStart || string.IsNullOrEmpty(m_internalToken.m_sText)) { continue; } m_internalToken.m_textType = TextType.VerseNumber; int verse = ScrReference.VerseToIntStart(m_internalToken.m_sText); if (verse != 0) { m_internalToken.m_startRef.Verse = verse; } verse = ScrReference.VerseToIntEnd(m_internalToken.m_sText); if (verse != 0) { m_internalToken.m_endRef.Verse = verse; } break; case ScrStyleNames.ChapterNumber: if (string.IsNullOrEmpty(m_internalToken.m_sText)) { continue; } int chapter = 0; try { chapter = ScrReference.ChapterToInt(m_internalToken.m_sText); } catch { // Ignore exceptions. We'll flag them later as errors. } if (!m_foundStart) { if (m_chapterNum != chapter) { continue; } m_foundStart = true; } else if (m_chapterNum > 0 && m_chapterNum != chapter) { // Stop if we're only getting tokens for a single chapter (unless // this is an (erroneous) second occurrence of the same chapter) return(false); } m_internalToken.m_textType = TextType.ChapterNumber; m_internalToken.m_startRef.Chapter = m_internalToken.m_endRef.Chapter = chapter; m_internalToken.m_startRef.Verse = m_internalToken.m_endRef.Verse = 1; break; default: { if (!m_foundStart) { continue; } // Deal with footnotes and picture captions Guid guidObj = TsStringUtils.GetGuidFromRun(m_currentScrText.m_paraTss, m_currentScrText.m_iRun, runProps); if (guidObj == Guid.Empty) { m_internalToken.m_textType = m_currentScrText.DefaultTextType; } else if (m_outerText != null) { // It was possible through copy/paste to put ORCs into footnotes or pictures, but that is no // longer allowed. This tokenizing code won't handle the nesting correctly, so just ignore // the nested ORC. See TE-8609. continue; } else { m_fOrcWasStartOfPara = m_internalToken.m_fParagraphStart; ICmObject obj; m_book.Cache.ServiceLocator.GetInstance <ICmObjectRepository>().TryGetObject(guidObj, out obj); if (obj is IStFootnote) { m_outerText = m_currentScrText; // footnotes are StTexts m_currentScrText = new TokenizableText((IStText)obj, TextType.Note); return(MoveNext()); } if (obj is ICmPicture) { m_outerText = m_currentScrText; ICmPicture pict = (ICmPicture)obj; m_currentScrText = new TokenizableText( pict.Caption.VernacularDefaultWritingSystem, ScrStyleNames.Figure, TextType.PictureCaption, pict, CmPictureTags.kflidCaption); return(MoveNext()); } } } break; } m_internalToken.m_fNoteStart = (m_internalToken.m_textType == TextType.Note && m_internalToken.m_fParagraphStart && m_currentScrText.m_iPara == 0); m_internalToken.m_paraStyleName = m_currentScrText.ParaStyleName; m_internalToken.m_charStyleName = charStyleName != null ? charStyleName : string.Empty; m_internalToken.m_object = m_currentScrText.m_obj; m_internalToken.m_flid = m_currentScrText.m_flid; // We need the current token to be a copy of our internal token so we don't change the // internal variables of whatever was returned from the enumerator. m_currentToken = m_internalToken.Copy(); return(true); } // Finished that paragraph and didn't find any more runs; try next para in this text, // if any. if (!m_currentScrText.NextParagraph()) { if (!m_foundStart) { Debug.Fail("We should have found the desired chapter wtihin the section we were searching."); return(false); } // Finished that text and didn't find any more paragraphs. // If we have been processing an inner text (footnote or picture caption), pop back // out to the "outer" one. if (m_outerText != null) { m_currentScrText = m_outerText; m_outerText = null; bool result = MoveNext(); if (result) { m_currentToken.m_fParagraphStart |= m_fOrcWasStartOfPara; m_fOrcWasStartOfPara = false; } return(result); } // Otherwise, try next text, if any. if (m_currentScrText.m_text.OwningFlid == ScrBookTags.kflidTitle) { // Get first section head text. CurrentSectionIndex = 0; } else if (m_currentScrText.m_text.OwningFlid == ScrSectionTags.kflidHeading) { m_currentScrText = new TokenizableText(m_currentSection.ContentOA, m_currentSection.IsIntro ? TextType.Other : TextType.Verse); } else { Debug.Assert(m_currentScrText.m_text.OwningFlid == ScrSectionTags.kflidContent); if (m_iCurrentSection + 1 >= m_book.SectionsOS.Count) { return(false); } CurrentSectionIndex++; if (m_chapterNum > 0 && ScrReference.GetChapterFromBcv(m_currentSection.VerseRefStart) != m_chapterNum) { return(false); } } } return(MoveNext()); }