Skip to content

Is there an Escape function so I can add user generated content to markdown and ensure it is escaped correctly #889

Description

@schallm

I'm working on writing some markdown from a system that allows user input. I want to include their text, but want to make sure their text doesn't get treated as markdown. I had AI create me a function, but was wondering if Markdig should have a built-in function for this kind of thing. Here is the function I'm using currently.

/// <summary>
/// Escapes user-entered text to prevent it from being interpreted as markdown.
/// This ensures user content is displayed as literal text rather than formatted markdown.
/// </summary>
/// <param name="text">The user-entered text to escape</param>
/// <returns>The escaped text safe for use in Markdown documents</returns>
public static string EscapeMarkdown(string text) {
    if (string.IsNullOrEmpty(text)) {
        return text;
    }

    // Dictionary of markdown special characters and their escaped equivalents
    var markdownChars = new Dictionary<char, string> {
        { '\\', @"\\" },  // Backslash must be first to avoid double-escaping
        { '*', @"\*" },   // Asterisk (bold/italic)
        { '_', @"\_" },   // Underscore (bold/italic)
        { '`', @"\`" },   // Backtick (code)
        { '#', @"\#" },   // Hash (headers)
        { '+', @"\+" },   // Plus (lists)
        { '-', @"\-" },   // Minus (lists, strikethrough)
        { '=', @"\=" },   // Equals (headers)
        { '|', @"\|" },   // Pipe (tables)
        { '{', @"\{" },   // Curly braces (various extensions)
        { '}', @"\}" },
        { '[', @"\[" },   // Square brackets (links, references)
        { ']', @"\]" },
        { '(', @"\(" },   // Parentheses (links)
        { ')', @"\)" },
        { '<', @"\<" },   // Angle brackets (HTML, autolinks)
        { '>', @"\>" },   // Greater than (blockquotes)
        { '!', @"\!" },   // Exclamation (images)
        { '~', @"\~" },   // Tilde (strikethrough)
        { '^', @"\^" },   // Caret (superscript in some dialects)
        { '.', @"\." },   // Period (can be part of lists when after numbers)
        { ':', @"\:" }    // Colon (definition lists in some dialects)
    };

    var result = new StringBuilder(text.Length * 2); // Pre-allocate for efficiency

    foreach (var c in text) {
        if (markdownChars.TryGetValue(c, out var escaped)) {
            result.Append(escaped);
        } else {
            result.Append(c);
        }
    }

    return result.ToString();
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions