<commit_before>using System;
using System.IO;
using System.Text.RegularExpressions;
using Markdig.Extensions.AutoLinks;
using NUnit.Framework;

namespace Markdig.Tests
{
    public class MiscTests
    {
        [Test]
        public void IsIssue356Corrected()
        {
            string input = @"https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97";
            string expected = @"<p><a href=""https://foo.bar/path/%5C#m4mv5W0GYKZpGvfA.97"">https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97</a></p>";

            TestParser.TestSpec($"<{input}>", expected);
            TestParser.TestSpec(input, expected, "autolinks|advanced");
        }

        [Test]
        public void TestAltTextIsCorrectlyEscaped()
        {
            TestParser.TestSpec(
                @"![This is image alt text with quotation ' and double quotation ""hello"" world](girl.png)",
                @"<p><img src=""girl.png"" alt=""This is image alt text with quotation ' and double quotation &quot;hello&quot; world"" /></p>");
        }

        [Test]
        public void TestChangelogPRLinksMatchDescription()
        {
            string solutionFolder = Path.GetFullPath(Path.Combine(TestParser.TestsDirectory, "../.."));
            string changelogPath = Path.Combine(solutionFolder, "changelog.md");
            string changelog = File.ReadAllText(changelogPath);
            var matches = Regex.Matches(changelog, @"\(\[\(PR #(\d+)\)\]\(.*?pull\/(\d+)\)\)");
            Assert.Greater(matches.Count, 0);<commit_msg>Add tests for balanced brackets in link text<commit_after>using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Markdig.Extensions.AutoLinks;
using NUnit.Framework;

namespace Markdig.Tests
{
    public class MiscTests
    {
        [TestCase("link [foo [bar]]")] // https://spec.commonmark.org/0.29/#example-508
        [TestCase("link [foo][bar]")]
        [TestCase("link [][foo][bar][]")]
        [TestCase("link [][foo][bar][[]]")]
        [TestCase("link [foo] [bar]")]
        [TestCase("link [[foo] [] [bar] [[abc]def]]")]
        [TestCase("[]")]
        [TestCase("[ ]")]
        [TestCase("[bar][]")]
        [TestCase("[bar][ foo]")]
        [TestCase("[bar][foo ][]")]
        [TestCase("[bar][fo[ ]o ][][]")]
        [TestCase("[a]b[c[d[e]f]g]h")]
        [TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o")]
        [TestCase("a[b[c[d]e]f[g]h]i[] [][foo][bar][] foo [j]k[l[m]n]o")]
        [TestCase("a[b[c[d]e]f[g]h]i foo [j]k[l[m]n]o[][]")]
        public void LinkTextMayContainBalancedBrackets(string linkText)
        {
            string markdown = $"[{linkText}](/uri)";
            string expected = $@"<p><a href=""/uri"">{linkText}</a></p>";

            TestParser.TestSpec(markdown, expected);

            // Make the link text unbalanced
            foreach (var bracketIndex in linkText
                .Select((c, i) => new Tuple<char, int>(c, i))
                .Where(t => t.Item1 == '[' || t.Item1 == ']')
                .Select(t => t.Item2))
            {
                string brokenLinkText = linkText.Remove(bracketIndex, 1);

                markdown = $"[{brokenLinkText}](/uri)";
                expected = $@"<p><a href=""/uri"">{brokenLinkText}</a></p>";

                string actual = Markdown.ToHtml(markdown);
                Assert.AreNotEqual(expected, actual);
            }
        }

        [Test]
        public void IsIssue356Corrected()
        {
            string input = @"https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97";
            string expected = @"<p><a href=""https://foo.bar/path/%5C#m4mv5W0GYKZpGvfA.97"">https://foo.bar/path/\#m4mv5W0GYKZpGvfA.97</a></p>";

            TestParser.TestSpec($"<{input}>", expected);
            TestParser.TestSpec(input, expected, "autolinks|advanced");
        }

        [Test]
        public void TestAltTextIsCorrectlyEscaped()
        {
            TestParser.TestSpec(
                @"![This is image alt text with quotation ' and double quotation ""hello"" world](girl.png)",
                @"<p><img src=""girl.png"" alt=""This is image alt text with quotation ' and double quotation &quot;hello&quot; world"" /></p>");
        }

        [Test]
        public void TestChangelogPRLinksMatchDescription()
        {
            string solutionFolder = Path.GetFullPath(Path.Combine(TestParser.TestsDirectory, "../.."));
            string changelogPath = Path.Combine(solutionFolder, "changelog.md");
            string changelog = File.ReadAllText(changelogPath);
            var matches = Regex.Matches(changelog, @"\(\[\(PR #(\d+)\)\]\(.*?pull\/(\d+)\)\)");
            Assert.Greater(matches.Count, 0);
{'fraction_non_alphanumeric': 0.18158347676419967, 'fraction_numerical': 0.010757314974182444, 'mean_word_length': 2.4539375928677565, 'pattern_counts': {'":': 0, '<': 28, '<?xml version=': 0, '>': 31, 'https://': 7, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7125397', 'n_tokens_mistral': 1557, 'n_tokens_neox': 1471, 'n_words': 260}