Example #1
0
        private static MTableRow CreateTableRow(
            OptionValue optionValue,
            ImmutableArray <OptionValueProvider> providers)
        {
            object?value      = null;
            string?shortValue = null;

            switch (optionValue)
            {
            case SimpleOptionValue simpleOptionValue:
            {
                value      = simpleOptionValue.Value;
                shortValue = simpleOptionValue.ShortValue;
                break;
            }

            case KeyValuePairOptionValue keyValuePairOptionValue:
            {
                string value2 = keyValuePairOptionValue.Value;

                if (OptionValueProvider.MetaValueRegex.IsMatch(value2) &&
                    providers.Any(f => f.Name == value2))
                {
                    value = Inline(
                        $"{keyValuePairOptionValue.Key}=",
                        Link(value2, MarkdownHelpers.CreateGitHubHeadingLink(value2)));
                }
                else
                {
                    value = $"{keyValuePairOptionValue.Key}={value2}";
                }

                shortValue = keyValuePairOptionValue.ShortKey;
                break;
            }
            }

            string description = _removeNewlineRegex.Replace(optionValue.Description ?? "", " ");

            return(TableRow(
                       value,
                       (string.IsNullOrEmpty(shortValue)) ? " " : shortValue,
                       (string.IsNullOrEmpty(description)) ? " " : description));
        }
Example #2
0
    public async Task <InlayHint> Handle(InlayHintResolveRequest request)
    {
        if (!_cache.TryGetFromCache(request.Hint, out var roslynHint, out var document))
        {
            return(request.Hint);
        }

        var descriptionTags = await roslynHint.GetDescriptionAsync(document, CancellationToken.None);

        StringBuilder stringBuilder = new StringBuilder();

        MarkdownHelpers.TaggedTextToMarkdown(
            descriptionTags,
            stringBuilder,
            _formattingOptions,
            MarkdownFormat.FirstLineAsCSharp,
            out _);

        return(request.Hint with
        {
            Tooltip = stringBuilder.ToString(),
        });
    }
Example #3
0
        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.
        /// This parameter is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // TODO: Prepare page for display here.

            // TODO: If your application contains multiple pages, ensure that you are
            // handling the hardware Back button by registering for the
            // Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
            // If you are using the NavigationHelper provided by some templates,
            // this event is handled for you.
            var helper = new MarkdownHelpers();
            var mdControl = new SnooDom.MarkdownControl();
            mdControl.StyleProvider = helper;
            mdControl.CommandFactory = helper;
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[A link with a /r/subreddit in it](/lol)");
            //Content = mdControl;
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("http://www.reddit.com");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[foo](http://en.wikipedia.org/wiki/Link_(film\\))");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("(http://tsfr.org)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[A link with a /r/subreddit in it](/lol)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[A link with a http://www.url.com in it](/lol)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Empty Link]()");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("http://en.wikipedia.org/wiki/café_racer");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("#####################################################hi");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[foo](http://bar\nbar)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Words words /r/test words");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("escaped \\/r/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("ampersands http://www.google.com?test&blah");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[_regular_ link with nesting](/test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM(" www.a.co?with&test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Normal^superscript");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Escape\\^superscript");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("~~normal strikethrough~~");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("\\~~escaped strikethrough~~");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("anywhere\\x03, you");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](//test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](//#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](git://github.com)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Speculation](//?)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/sr_with_underscores");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](///#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/multireddit+test+yay");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("<test>");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("words_with_underscores");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("words*with*asterisks");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("~test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test/m/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/U/nope");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/m/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/w/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/comments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test/commentscommentscommentscommentscommentscommentscomments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/commentscommentscommentscommentscommentscommentscomments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("blah \\\\");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/whatever: fork");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/t:timereddit");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/reddit.com");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/not.cool");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/very+clever+multireddit+reddit.com+t:fork+yay");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/t:heatdeathoftheuniverse");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/all-minus-something");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/all-minus-something");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/notall-minus");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/R/reddit.com");
        }
Example #4
0
        /// <summary>
        /// Invoked when this page is about to be displayed in a Frame.
        /// </summary>
        /// <param name="e">Event data that describes how this page was reached.
        /// This parameter is typically used to configure the page.</param>
        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            // TODO: Prepare page for display here.

            // TODO: If your application contains multiple pages, ensure that you are
            // handling the hardware Back button by registering for the
            // Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
            // If you are using the NavigationHelper provided by some templates,
            // this event is handled for you.
            var helper    = new MarkdownHelpers();
            var mdControl = new SnooDom.MarkdownControl();

            mdControl.StyleProvider  = helper;
            mdControl.CommandFactory = helper;
            mdControl.Markdown       = SnooDom.SnooDom.MarkdownToDOM("[A link with a /r/subreddit in it](/lol)");
            //Content = mdControl;
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("http://www.reddit.com");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[foo](http://en.wikipedia.org/wiki/Link_(film\\))");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("(http://tsfr.org)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[A link with a /r/subreddit in it](/lol)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[A link with a http://www.url.com in it](/lol)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Empty Link]()");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("http://en.wikipedia.org/wiki/café_racer");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("#####################################################hi");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[foo](http://bar\nbar)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Words words /r/test words");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("escaped \\/r/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("ampersands http://www.google.com?test&blah");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[_regular_ link with nesting](/test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM(" www.a.co?with&test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Normal^superscript");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("Escape\\^superscript");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("~~normal strikethrough~~");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("\\~~escaped strikethrough~~");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("anywhere\\x03, you");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](//test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](//#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](git://github.com)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Speculation](//?)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/sr_with_underscores");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("[Test](///#test)");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/multireddit+test+yay");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("<test>");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("words_with_underscores");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("words*with*asterisks");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("~test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test/m/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/U/nope");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/m/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/w/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/comments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/u/test/commentscommentscommentscommentscommentscommentscomments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/test/commentscommentscommentscommentscommentscommentscomments/test test");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("blah \\\\");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/whatever: fork");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/t:timereddit");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/reddit.com");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/not.cool");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/very+clever+multireddit+reddit.com+t:fork+yay");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/t:heatdeathoftheuniverse");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/all-minus-something");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/all-minus-something");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/r/notall-minus");
            mdControl.Markdown = SnooDom.SnooDom.MarkdownToDOM("/R/reddit.com");
        }
Example #5
0
        private static void Main(params string[] args)
        {
            IEnumerable <Command> commands = CommandLoader.LoadCommands(typeof(CommandLoader).Assembly)
                                             .Select(c => c.WithOptions(c.Options.OrderBy(f => f, CommandOptionComparer.Name)))
                                             .OrderBy(c => c.Name, StringComparer.InvariantCulture);

            var application = new CommandLineApplication(
                "orang",
                "Search, replace, rename and delete files and its content using the power of .NET regular expressions.",
                commands.OrderBy(f => f.Name, StringComparer.InvariantCulture));

            string?destinationDirectoryPath = null;
            string?dataDirectoryPath        = null;

            if (Debugger.IsAttached)
            {
                destinationDirectoryPath = (args.Length > 0) ? args[0] : @"..\..\..\..\..\docs\cli";
                dataDirectoryPath        = @"..\..\..\data";
            }
            else
            {
                destinationDirectoryPath = args[0];
                dataDirectoryPath        = @"..\src\DocumentationGenerator\data";
            }

            string readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "README.md"));

            var settings = new MarkdownWriterSettings(
                MarkdownFormat.Default.WithTableOptions(
                    MarkdownFormat.Default.TableOptions | TableOptions.FormatHeaderAndContent));

            using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                using (MarkdownWriter mw = MarkdownWriter.Create(sw, settings))
                {
                    mw.WriteStartHeading(1);
                    mw.WriteString("Orang Command-Line Interface");
                    mw.WriteRaw(" <img align=\"left\" src=\"../../images/icon48.png\">");
                    mw.WriteEndHeading();
                    mw.WriteString(application.Description);
                    mw.WriteLine();

                    mw.WriteHeading2("Commands");

                    Table(
                        TableRow("Command", "Description"),
                        application
                        .Commands
                        .Select(f => TableRow(Link(f.Name, f.Name + "-command.md"), f.Description)))
                    .WriteTo(mw);

                    mw.WriteLine();

                    string readmeLinksFilePath = Path.Combine(dataDirectoryPath, "readme_bottom.md");

                    if (File.Exists(readmeLinksFilePath))
                    {
                        mw.WriteRaw(File.ReadAllText(readmeLinksFilePath));
                    }

                    WriteFootNote(mw);

                    Console.WriteLine(readmeFilePath);
                }

            string valuesFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, "OptionValues.md"));

            ImmutableArray <OptionValueProvider> providers = OptionValueProvider.GetProviders(
                commands.SelectMany(f => f.Options),
                OptionValueProviders.ProvidersByName.Select(f => f.Value))
                                                             .ToImmutableArray();

            MDocument document = Document(
                Heading1("List of Option Values"),
                BulletList(providers.Select(f => Link(
                                                f.Name,
                                                MarkdownHelpers.CreateGitHubHeadingLink(f.Name)))),
                providers.Select(provider =>
            {
                return(new MObject[]
                {
                    Heading2(provider.Name),
                    Table(
                        TableRow("Value", " ", "Description"),
                        provider.Values.Select(f => CreateTableRow(f, providers)))
                });
            }));

            document.Add(
                Heading2("Expression Syntax"),
                Table(
                    TableRow("Expression", "Description"),
                    HelpProvider.GetExpressionItems(includeDate: true)
                    .Select(f => TableRow(InlineCode(f.expression), f.description))));

            AddFootnote(document);

            var markdownFormat = new MarkdownFormat(
                tableOptions: MarkdownFormat.Default.TableOptions | TableOptions.FormatContent);

            File.WriteAllText(valuesFilePath, document.ToString(markdownFormat));

            foreach (Command command in application.Commands)
            {
                readmeFilePath = Path.GetFullPath(Path.Combine(destinationDirectoryPath, $"{command.Name}-command.md"));

                using (var sw = new StreamWriter(readmeFilePath, append: false, Encoding.UTF8))
                    using (MarkdownWriter mw = MarkdownWriter.Create(sw))
                    {
                        var writer = new DocumentationWriter(mw);

                        writer.WriteCommandHeading(command, application);
                        writer.WriteCommandDescription(command);

                        mw.WriteLink("Home", "README.md#readme");

                        foreach (string section in new[] { "Synopsis", "Arguments", "Options", "Samples" })
                        {
                            mw.WriteString(" ");
                            mw.WriteCharEntity((char)0x2022);
                            mw.WriteString(" ");
                            mw.WriteLink(section, "#" + section);
                        }

                        mw.WriteLine();

                        writer.WriteCommandSynopsis(command, application);
                        writer.WriteArguments(command.Arguments);
                        writer.WriteOptions(command.Options);

                        string samplesFilePath = Path.Combine(dataDirectoryPath, command.Name + "_bottom.md");

                        if (File.Exists(samplesFilePath))
                        {
                            string content = File.ReadAllText(samplesFilePath);
                            mw.WriteRaw(content);
                        }

                        WriteFootNote(mw);

                        Console.WriteLine(readmeFilePath);
                    }
            }

            Console.WriteLine("Done");

            if (Debugger.IsAttached)
            {
                Console.ReadKey();
            }
        }
Example #6
0
        public override void WriteOptionDescription(CommandOption option)
        {
            _writer.WriteString(option.Description);

            if (TryGetProvider(option, out OptionValueProvider? provider))
            {
                if (!string.IsNullOrEmpty(option.Description))
                {
                    _writer.WriteLine();
                    _writer.WriteLine();
                }

                OptionValueProvider?provider2 = provider;

                if (provider.Parent != null)
                {
                    provider2 = provider.Parent;
                }

                string metaValueUrl = provider2.Name;

                _writer.WriteLink(provider2.Name, "OptionValues.md" + MarkdownHelpers.CreateGitHubHeadingLink(metaValueUrl));

                _writer.WriteString(": ");

                using (IEnumerator <string> en = provider
                                                 .Values
                                                 .Where(f => !f.Hidden)
                                                 .Select(f => f.HelpValue)
                                                 .GetEnumerator())
                {
                    if (en.MoveNext())
                    {
                        while (true)
                        {
                            string value = en.Current;

                            Match metaValueMatch = Regex.Match(value, @"(?<==)\<[\p{Lu}_]+>\z");

                            if (metaValueMatch.Success &&
                                OptionValueProviders.ProvidersByName.ContainsKey(metaValueMatch.Value))
                            {
                                _writer.WriteInlineCode(value.Remove(metaValueMatch.Index));
                                _writer.WriteLink(
                                    metaValueMatch.Value,
                                    "OptionValues.md" + MarkdownHelpers.CreateGitHubHeadingLink(metaValueMatch.Value));
                            }
                            else
                            {
                                _writer.WriteInlineCode(en.Current);
                            }

                            if (en.MoveNext())
                            {
                                _writer.WriteString(", ");
                            }
                            else
                            {
                                break;
                            }
                        }

                        _writer.WriteString(".");
                    }
                }
            }

            if (!string.IsNullOrEmpty(option.Description) ||
                provider != null)
            {
                _writer.WriteLine();
                _writer.WriteLine();
            }
        }
        public async Task <QuickInfoResponse> Handle(QuickInfoRequest request, Document document)
        {
            var response = new QuickInfoResponse();

            if (document is null)
            {
                return(response);
            }

            var quickInfoService = QuickInfoService.GetService(document);

            if (quickInfoService is null)
            {
                _logger?.LogWarning($"QuickInfo service was null for {document.FilePath}");
                return(response);
            }

            var sourceText = await document.GetTextAsync();

            var position = sourceText.GetTextPosition(request);

            var quickInfo = await quickInfoService.GetQuickInfoAsync(document, position);

            if (quickInfo is null)
            {
                _logger?.LogTrace($"No QuickInfo found for {document.FilePath}:{request.Line},{request.Column}");
                return(response);
            }

            var finalTextBuilder = new StringBuilder();

            bool lastSectionHadLineBreak = true;
            var  description             = quickInfo.Sections.FirstOrDefault(s => s.Kind == QuickInfoSectionKinds.Description);

            if (description is object)
            {
                appendSection(description, MarkdownFormat.AllTextAsCSharp);
            }

            var summary = quickInfo.Sections.FirstOrDefault(s => s.Kind == QuickInfoSectionKinds.DocumentationComments);

            if (summary is object)
            {
                appendSection(summary, MarkdownFormat.Default);
            }

            foreach (var section in quickInfo.Sections)
            {
                switch (section.Kind)
                {
                case QuickInfoSectionKinds.Description:
                case QuickInfoSectionKinds.DocumentationComments:
                    continue;

                case QuickInfoSectionKinds.TypeParameters:
                    appendSection(section, MarkdownFormat.AllTextAsCSharp);
                    break;

                case QuickInfoSectionKinds.AnonymousTypes:
                    // The first line is "Anonymous Types:"
                    // Then we want all anonymous types to be C# highlighted
                    appendSection(section, MarkdownFormat.FirstLineDefaultRestCSharp);
                    break;

                case NullabilityAnalysis:
                    // Italicize the nullable analysis for emphasis.
                    appendSection(section, MarkdownFormat.Italicize);
                    break;

                default:
                    appendSection(section, MarkdownFormat.Default);
                    break;
                }
            }

            response.Markdown = finalTextBuilder.ToString().Trim();

            return(response);

            void appendSection(QuickInfoSection section, MarkdownFormat format)
            {
                if (!lastSectionHadLineBreak && !section.TaggedParts.StartsWithNewline())
                {
                    finalTextBuilder.Append(_formattingOptions.NewLine);
                    finalTextBuilder.Append(_formattingOptions.NewLine);
                }
                MarkdownHelpers.TaggedTextToMarkdown(section.TaggedParts, finalTextBuilder, _formattingOptions, format, out lastSectionHadLineBreak);
            }
        }