public TagSegment GetFirstTagOnSegment(TextTagsState state) { int? openedIndex, closedIndex; TagName?tagName; while (true) { openedIndex = GetIndexTagBracket(state, IsOpenedTag, null, false); if (!openedIndex.HasValue) { return(null); } state = state.ChangeSegment(openedIndex.Value, state.End); tagName = GetTagName(state, IsOpenedTag); var indexInTag = openedIndex.Value + Tags.GetMd(tagName.Value).Length; if (indexInTag > state.End) { return(null); } state = state.ChangeSegment(indexInTag, state.End); closedIndex = GetIndexTagBracket(state, IsClosedTag, tagName, true); if (!closedIndex.HasValue || IsEmptyInsideTag(closedIndex, openedIndex, tagName)) { continue; } break; } return(new TagSegment(tagName.Value, openedIndex.Value, closedIndex.Value)); }
private IEnumerable <TagSegment> GetAllTags(TextTagsState state) { var nextStates = new Stack <TextTagsState>(); for (var index = 0; index < state.Text.Length; index++) { var tag = finder.GetFirstTagOnSegment(state); if (tag == null) { if (nextStates.Count == 0) { break; } index = nextStates.Peek().Start - 1; state = nextStates.Pop(); continue; } yield return(tag); var newStart = tag.CloseIndex + Tags.GetMd(tag.TagName).Length; if (newStart < state.End) { nextStates.Push(state.ChangeSegment(newStart, state.End)); } index = tag.OpenIndex + Tags.GetMd(tag.TagName).Length; if (index <= state.End - 1) { state = state.SwitchTag(tag.TagName).ChangeSegment(index, tag.CloseIndex - 1); } index -= 1; } }
private int?GetIndexTagBracket( TextTagsState state, Func <TagName, TextTagsState, bool> condition, TagName?expectedTagName, bool isEqual) { return(Enumerable .Range(state.Start, state.End - state.Start + 1) .Cast <int?>() .FirstOrDefault(i => Equals(GetTagName(state.ChangeSegment(i.Value, state.End), condition), expectedTagName) == isEqual)); }