This class represents the segments of a single verse (or chapter)
Ejemplo n.º 1
0
        /// <summary>
        /// Make the necessary Free Translation annotation comments for the specified group
        /// of roughly matching segments. In general, we transfer corresponding material from
        /// the BT segment to the FT annotation of the main paragraph segment, with any left-over
        /// paragraph segments blank, and any left-over BT segments added to the end of the
        /// last FT segment. As a special case, if some FTs at the end of the list already have the
        /// exact text of corresponding BT ones (counting from the end of the lists), we assume that
        /// those pairs correspond, even if not in corresponding positions counting from the start,
        /// and don't change them. This helps preserve alignment when something may merge or split
        /// a segment in the base text after much of it is annotated.
        /// </summary>
        /// <param name="igroup"></param>
        private void MakeSegmentBtsForGroup(int igroup)
        {
            SegGroup group = m_segGroups[igroup];

            // Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
            DiscardMatchingSegsAtEnd(group);
            // The remaining (often all) segments are transferred one-for-one. (We don't need to check for
            // exactly matching ones at the start, because in that case, copying will be a no-op.)
            for (int iParaSeg = 0; iParaSeg < group.ParaSegs.Count; iParaSeg++)
            {
                // We may assume hvoFt is non-zero, because LoadSegmentFreeTranslations ensures every segment has one.
                var seg = group.ParaSegs[iParaSeg];
                if (iParaSeg >= group.BtSegs.Count)
                {
                    // no more Bt segments, make the annotation FT empty (in case set previously).
                    // But don't overwrite if unchanged, since PropChanged can do a good deal of work
                    // and sometimes destroy selections we want to preserve.
                    if (seg.FreeTranslation.get_String(m_wsBt).Length != 0)
                    {
                        seg.FreeTranslation.set_String(m_wsBt, string.Empty);
                    }
                    continue;
                }
                ITsString tssFt = group.BtSegs[iParaSeg].String;
                tssFt = InsertOrphanBtFromPreviousGroup(igroup, iParaSeg, tssFt);
                tssFt = AppendLeftoverBtToLastSeg(group, iParaSeg, tssFt);
                // But don't overwrite if unchanged, since PropChanged can do a good deal of work
                // and sometimes destroy selections we want to preserve.
                if (!seg.FreeTranslation.get_String(m_wsBt).Equals(tssFt))
                {
                    seg.FreeTranslation.set_String(m_wsBt, tssFt);
                }
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// If this paragraph segment is the last one for its group, but there are left-over BT segments,
 /// append them to this.
 /// </summary>
 /// <param name="group"></param>
 /// <param name="iParaSeg"></param>
 /// <param name="tssFt"></param>
 /// <returns></returns>
 private ITsString AppendLeftoverBtToLastSeg(SegGroup group, int iParaSeg, ITsString tssFt)
 {
     if (iParaSeg == group.ParaSegs.Count - 1 && iParaSeg < group.BtSegs.Count - 1)
     {
         // We have left over translations. Append them.
         ITsStrBldr bldr = tssFt.GetBldr();
         for (int j = iParaSeg + 1; j < group.BtSegs.Count; j++)
         {
             AppendWithOptionalSpace(bldr, group.BtSegs[j].String);
         }
         tssFt = bldr.GetString();
     }
     return(tssFt);
 }
Ejemplo n.º 3
0
        /// <summary>
        /// If this is the first segment in the group and NOT the first group, check for the possibility that
        /// there was no segment to attach the previous group's BTs to. I think this can only
        /// happen for the first group. Put the orphan BT at the start of this segment so it isn't lost.
        /// </summary>
        /// <param name="igroup"></param>
        /// <param name="iParaSeg"></param>
        /// <param name="tssFt"></param>
        /// <returns></returns>
        private ITsString InsertOrphanBtFromPreviousGroup(int igroup, int iParaSeg, ITsString tssFt)
        {
            if (iParaSeg == 0 && igroup > 0 && m_segGroups[igroup - 1].ParaSegs.Count == 0)
            {
                ITsStrBldr bldr      = TsStrBldrClass.Create();
                SegGroup   prevGroup = m_segGroups[igroup - 1];
                foreach (TsStringSegment seg in prevGroup.BtSegs)
                {
                    AppendWithOptionalSpace(bldr, seg.String);
                }

                AppendWithOptionalSpace(bldr, tssFt);
                tssFt = bldr.GetString();
            }
            return(tssFt);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// We have determined that corresponding groups start at iStartSegPara in m_paraSegs/m_segments and
        /// iStartSegBt in m_BtSegs. Make a SegGroup out of the corresponding segments and return the
        /// index of the indexes of the starts of the next group (in each case one more than the index of
        /// the matching verse segment which ended the group in the paragraph sequence). One or both indexes might
        /// be greater than the length of the corresponding array, indicating that the group extends to the end.
        /// One or both parts of the group might be empty.
        /// </summary>
        /// <returns>start index of next para segment (and next BT one in startOfNextBtSeg)</returns>
        int MakeGroup(int iStartSegPara, int iStartSegBt, out int startOfNextBtSeg)
        {
            SegGroup group = new SegGroup();

            m_segGroups.Add(group);
            int iLimSegPara = iStartSegPara;

            startOfNextBtSeg = -1;
            for (; iLimSegPara < m_segments.Count; iLimSegPara++)
            {
                // The group also ends here if it is a CV-styled run and we can find a matching one in the BT.
                if (m_labelSegIndexes.Contains(iLimSegPara))
                {
                    var       seg     = m_segments[iLimSegPara];
                    ITsString targetT = ConvertedBtLabel(seg);
                    startOfNextBtSeg = IndexOfMatchingVerseSegInBt(targetT, iStartSegBt);
                    if (startOfNextBtSeg < 0)
                    {
                        // We failed to find a match at the location we expected, so just try search the whole BT
                        startOfNextBtSeg = IndexOfMatchingVerseSegInBt(targetT, 0);
                    }
                    if (startOfNextBtSeg >= 0)
                    {
                        startOfNextBtSeg++;                         // actual contents starts AFTER the common label
                        break;
                    }
                }
            }
            // Make the group's ParaSegs be the non-label segments from the range we decided.
            var paraSegs = new List <ISegment>(iLimSegPara - iStartSegPara);

            for (int i = iStartSegPara; i < iLimSegPara; i++)
            {
                if (!m_labelSegIndexes.Contains(i))
                {
                    paraSegs.Add(m_segments[i]);
                }
            }
            group.ParaSegs = paraSegs;
            group.BtSegs   = GetSegGroup(iStartSegBt);
            return(iLimSegPara + 1);
        }
Ejemplo n.º 5
0
        // Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
        private void DiscardMatchingSegsAtEnd(SegGroup group)
        {
            int ipara  = group.ParaSegs.Count - 1;
            int itrans = group.BtSegs.Count - 1;

            while (ipara > 0 && itrans > 0)
            {
                // See if the existing FT matches
                string desiredFT = group.BtSegs[itrans].Text;
                var    seg       = group.ParaSegs[ipara];
                string currentFT = seg.FreeTranslation.get_String(m_wsBt).Text;
                if (desiredFT != currentFT)
                {
                    break;
                }
                // The two last items are already identical, don't need to do anything more about them.
                group.BtSegs.RemoveAt(itrans);
                group.ParaSegs.RemoveAt(ipara);
                itrans--;
                ipara--;
            }
        }
Ejemplo n.º 6
0
		/// <summary>
		/// We have determined that corresponding groups start at iStartSegPara in m_paraSegs/m_segments and
		/// iStartSegBt in m_BtSegs. Make a SegGroup out of the corresponding segments and return the
		/// index of the indexes of the starts of the next group (in each case one more than the index of
		/// the matching verse segment which ended the group in the paragraph sequence). One or both indexes might
		/// be greater than the length of the corresponding array, indicating that the group extends to the end.
		/// One or both parts of the group might be empty.
		/// </summary>
		/// <returns>start index of next para segment (and next BT one in startOfNextBtSeg)</returns>
		int MakeGroup(int iStartSegPara, int iStartSegBt, out int startOfNextBtSeg)
		{
			SegGroup group = new SegGroup();
			m_segGroups.Add(group);
			int iLimSegPara = iStartSegPara;
			startOfNextBtSeg = -1;
			for (; iLimSegPara < m_segments.Count; iLimSegPara++)
			{
				// The group also ends here if it is a CV-styled run and we can find a matching one in the BT.
				if (m_labelSegIndexes.Contains(iLimSegPara))
				{
					var seg = m_segments[iLimSegPara];
					ITsString targetT = ConvertedBtLabel(seg);
					startOfNextBtSeg = IndexOfMatchingVerseSegInBt(targetT, iStartSegBt);
					if (startOfNextBtSeg < 0)
					{
						// We failed to find a match at the location we expected, so just try search the whole BT
						startOfNextBtSeg = IndexOfMatchingVerseSegInBt(targetT, 0);
					}
					if (startOfNextBtSeg >= 0)
					{
						startOfNextBtSeg++; // actual contents starts AFTER the common label
						break;
					}
				}
			}
			// Make the group's ParaSegs be the non-label segments from the range we decided.
			var paraSegs = new List<ISegment>(iLimSegPara - iStartSegPara);
			for (int i = iStartSegPara; i < iLimSegPara; i++)
			{
				if (!m_labelSegIndexes.Contains(i))
					paraSegs.Add(m_segments[i]);
			}
			group.ParaSegs = paraSegs;
			group.BtSegs = GetSegGroup(iStartSegBt);
			return iLimSegPara + 1;
		}
Ejemplo n.º 7
0
		/// <summary>
		/// If this paragraph segment is the last one for its group, but there are left-over BT segments,
		/// append them to this.
		/// </summary>
		/// <param name="group"></param>
		/// <param name="iParaSeg"></param>
		/// <param name="tssFt"></param>
		/// <returns></returns>
		private ITsString AppendLeftoverBtToLastSeg(SegGroup group, int iParaSeg, ITsString tssFt)
		{
			if (iParaSeg == group.ParaSegs.Count - 1 && iParaSeg < group.BtSegs.Count - 1)
			{
				// We have left over translations. Append them.
				ITsStrBldr bldr = tssFt.GetBldr();
				for (int j = iParaSeg + 1; j < group.BtSegs.Count; j++)
					AppendWithOptionalSpace(bldr, group.BtSegs[j].String);
				tssFt = bldr.GetString();
			}
			return tssFt;
		}
Ejemplo n.º 8
0
		// Discard any items at the end of both lists which already match exactly. Leave at least one in each group.
		private void DiscardMatchingSegsAtEnd(SegGroup group)
		{
			int ipara = group.ParaSegs.Count - 1;
			int itrans = group.BtSegs.Count - 1;
			while (ipara > 0 && itrans > 0)
			{
				// See if the existing FT matches
				string desiredFT = group.BtSegs[itrans].Text;
				var seg = group.ParaSegs[ipara];
				string currentFT = seg.FreeTranslation.get_String(m_wsBt).Text;
				if (desiredFT != currentFT)
					break;
				// The two last items are already identical, don't need to do anything more about them.
				group.BtSegs.RemoveAt(itrans);
				group.ParaSegs.RemoveAt(ipara);
				itrans--;
				ipara--;
			}
		}