/// <summary> /// Emits a stream of events /// </summary> /// <param name="fragments">The lexed HTML fragments</param> /// <param name="matchElement">A function to match which element should be considered the "outside" element to process</param> /// <param name="includeClosingElementWithin"> /// If true, IsWithin will be true of the final closing element. This can be handy /// for handling different scenarios. For extracting with the outer value, you probably want this to be true. /// For extrating just the inner value, you would want this to be false. /// </param> /// <returns></returns> public static IEnumerable <WithinElementDomElementEvent> WithInElement(this IEnumerable <Fragment> fragments, Func <Fragment, bool> matchElement, bool includeClosingElementWithin) { bool isInsideFragment = false; int stack = 0; foreach (var item in LexedDomParser.Execute(fragments)) { switch (item.Type) { case DomElementEventType.Push: case DomElementEventType.Child: if (isInsideFragment) { yield return(new WithinElementDomElementEvent(item, true)); if (item.Type == DomElementEventType.Push) { stack++; } } else { if (matchElement(item.Fragment)) { isInsideFragment = true; stack = 1; yield return(new WithinElementDomElementEvent(item, true)); } else { yield return(new WithinElementDomElementEvent(item, false)); } } break; case DomElementEventType.Pop: if (isInsideFragment) { stack--; if (stack <= 0) { isInsideFragment = false; } yield return(new WithinElementDomElementEvent(item, includeClosingElementWithin ? true : isInsideFragment)); } else { yield return(new WithinElementDomElementEvent(item, false)); } break; } } }
public static IEnumerable <DomElementEvent> Execute(IEnumerable <Fragment> fragments) { var parser = new LexedDomParser(); return(parser._Execute(fragments)); }