public static Paragraph Parse(string text, Style?style = null) { if (text is null) { throw new ArgumentNullException(nameof(text)); } style ??= Style.Plain; var result = new Paragraph(); using var tokenizer = new MarkupTokenizer(text); var stack = new Stack <Style>(); while (tokenizer.MoveNext()) { var token = tokenizer.Current; if (token == null) { break; } if (token.Kind == MarkupTokenKind.Open) { var parsedStyle = StyleParser.Parse(token.Value); stack.Push(parsedStyle); } else if (token.Kind == MarkupTokenKind.Close) { if (stack.Count == 0) { throw new InvalidOperationException($"Encountered closing tag when none was expected near position {token.Position}."); } stack.Pop(); } else if (token.Kind == MarkupTokenKind.Text) { // Get the effective style. var effectiveStyle = style.Combine(stack.Reverse()); result.Append(Emoji.Replace(token.Value), effectiveStyle); } else { throw new InvalidOperationException("Encountered unknown markup token."); } } if (stack.Count > 0) { throw new InvalidOperationException("Unbalanced markup stack. Did you forget to close a tag?"); } return(result); }
/// <summary> /// Removes markup from the specified string. /// </summary> /// <param name="text">The text to remove markup from.</param> /// <returns>A string that does not have any markup.</returns> public static string RemoveMarkup(this string?text) { if (string.IsNullOrWhiteSpace(text)) { return(string.Empty); } var result = new StringBuilder(); var tokenizer = new MarkupTokenizer(text); while (tokenizer.MoveNext() && tokenizer.Current != null) { if (tokenizer.Current.Kind == MarkupTokenKind.Text) { result.Append(tokenizer.Current.Value); } } return(result.ToString()); }