├── .editorconfig ├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ ├── ci.yml │ └── nuget_org_only.config ├── .gitignore ├── changelog.md ├── contributing.md ├── doc ├── parsing-ast.md ├── parsing-extensions.md └── parsing-overview.md ├── img ├── markdig.png ├── markdig.svg ├── markdig128.png └── markdig64.png ├── license.txt ├── readme.md └── src ├── Markdig.Benchmarks ├── CommonMarkLib.cs ├── Markdig.Benchmarks.csproj ├── Program.cs ├── TestMatchPerf.cs ├── TestStringPerf.cs ├── cmark.dll └── spec.md ├── Markdig.Signed ├── Markdig.Signed.csproj └── key.snk ├── Markdig.Tests ├── ArgumentOutOfRangeException.md ├── GlobalUsings.cs ├── Markdig.Tests.csproj ├── Markdig.Tests.csproj.DotSettings ├── MiscTests.cs ├── NormalizeSpecs │ ├── Headings.generated.cs │ └── Headings.md ├── PlainTextSpecs │ ├── SamplePlainText.generated.cs │ └── SamplePlainText.md ├── Program.cs ├── RoundtripSpecs │ ├── CommonMark.generated.cs │ ├── CommonMark.md │ ├── Inlines │ │ ├── TestAutoLinkInline.cs │ │ ├── TestBackslashEscapeInline.cs │ │ ├── TestCodeInline.cs │ │ ├── TestEmphasisInline.cs │ │ ├── TestHtmlEntityInline.cs │ │ ├── TestHtmlInline.cs │ │ ├── TestImageInline.cs │ │ ├── TestLineBreakInline.cs │ │ ├── TestLinkInline.cs │ │ └── TestNullCharacterInline.cs │ ├── TestAtxHeading.cs │ ├── TestExample.cs │ ├── TestFencedCodeBlock.cs │ ├── TestHtmlBlock.cs │ ├── TestIndentedCodeBlock.cs │ ├── TestLinkReferenceDefinition.cs │ ├── TestNoBlocksFoundBlock.cs │ ├── TestOrderedList.cs │ ├── TestParagraph.cs │ ├── TestQuoteBlock.cs │ ├── TestSetextHeading.cs │ ├── TestThematicBreak.cs │ ├── TestUnorderedList.cs │ └── TestYamlFrontMatterBlock.cs ├── Specs │ ├── AbbreviationSpecs.generated.cs │ ├── AbbreviationSpecs.md │ ├── AlertBlockSpecs.generated.cs │ ├── AlertBlockSpecs.md │ ├── AutoIdentifierSpecs.generated.cs │ ├── AutoIdentifierSpecs.md │ ├── AutoLinks.generated.cs │ ├── AutoLinks.md │ ├── BootstrapSpecs.generated.cs │ ├── BootstrapSpecs.md │ ├── CommonMark.generated.cs │ ├── CommonMark.md │ ├── CustomContainerSpecs.generated.cs │ ├── CustomContainerSpecs.md │ ├── DefinitionListSpecs.generated.cs │ ├── DefinitionListSpecs.md │ ├── DiagramsSpecs.generated.cs │ ├── DiagramsSpecs.md │ ├── EmojiSpecs.generated.cs │ ├── EmojiSpecs.md │ ├── EmphasisExtraSpecs.generated.cs │ ├── EmphasisExtraSpecs.md │ ├── FigureFooterAndCiteSpecs.generated.cs │ ├── FigureFooterAndCiteSpecs.md │ ├── FootnotesSpecs.generated.cs │ ├── FootnotesSpecs.md │ ├── GenericAttributesSpecs.generated.cs │ ├── GenericAttributesSpecs.md │ ├── GlobalizationSpecs.generated.cs │ ├── GlobalizationSpecs.md │ ├── GridTableSpecs.generated.cs │ ├── GridTableSpecs.md │ ├── HardlineBreakSpecs.generated.cs │ ├── HardlineBreakSpecs.md │ ├── JiraLinks.generated.cs │ ├── JiraLinks.md │ ├── ListExtraSpecs.generated.cs │ ├── ListExtraSpecs.md │ ├── MathSpecs.generated.cs │ ├── MathSpecs.md │ ├── MediaSpecs.generated.cs │ ├── MediaSpecs.md │ ├── NoHtmlSpecs.generated.cs │ ├── NoHtmlSpecs.md │ ├── PipeTableGfmSpecs.generated.cs │ ├── PipeTableGfmSpecs.md │ ├── PipeTableSpecs.generated.cs │ ├── PipeTableSpecs.md │ ├── SmartyPantsSpecs.generated.cs │ ├── SmartyPantsSpecs.md │ ├── TaskListSpecs.generated.cs │ ├── TaskListSpecs.md │ ├── YamlSpecs.generated.cs │ ├── YamlSpecs.md │ └── readme.md ├── TestAutoLinks.cs ├── TestCharHelper.cs ├── TestConfigureNewLine.cs ├── TestContainerBlocks.cs ├── TestContainerInlines.cs ├── TestCustomEmojis.cs ├── TestDescendantsOrder.cs ├── TestEmphasisExtended.cs ├── TestEmphasisExtraOptions.cs ├── TestEmphasisPlus.cs ├── TestExceptionNotThrown.cs ├── TestFastStringWriter.cs ├── TestFencedCodeBlocks.cs ├── TestHtmlAttributes.cs ├── TestHtmlCodeBlocks.cs ├── TestHtmlHelper.cs ├── TestImageAltText.cs ├── TestLazySubstring.cs ├── TestLineReader.cs ├── TestLinkHelper.cs ├── TestLinkRewriter.cs ├── TestMarkdigCoreApi.cs ├── TestMediaLinks.cs ├── TestNewLine.cs ├── TestNormalize.cs ├── TestOrderedList.cs ├── TestParser.cs ├── TestPipeTable.cs ├── TestPlainText.cs ├── TestPlayParser.cs ├── TestPragmaLines.cs ├── TestReferralLinks.cs ├── TestRelativeUrlReplacement.cs ├── TestRoundtrip.cs ├── TestSmartyPants.cs ├── TestSourcePosition.cs ├── TestStringSliceList.cs ├── TestTransformedStringCache.cs ├── TestYamlFrontMatterExtension.cs ├── TextAssert.cs └── hang.md ├── Markdig.WebApp ├── ApiController.cs ├── Connected Services │ └── Application Insights │ │ └── ConnectedService.json ├── Markdig.WebApp.csproj ├── Program.cs ├── Properties │ └── launchSettings.json ├── Startup.cs └── appsettings.json ├── Markdig ├── Diagrams │ ├── Parsers.cd │ ├── Renderers.cd │ └── Syntax.cd ├── Extensions │ ├── Abbreviations │ │ ├── Abbreviation.cs │ │ ├── AbbreviationExtension.cs │ │ ├── AbbreviationHelper.cs │ │ ├── AbbreviationInline.cs │ │ ├── AbbreviationParser.cs │ │ └── HtmlAbbreviationRenderer.cs │ ├── Alerts │ │ ├── AlertBlock.cs │ │ ├── AlertBlockRenderer.cs │ │ ├── AlertExtension.cs │ │ └── AlertInlineParser.cs │ ├── AutoIdentifiers │ │ ├── AutoIdentifierExtension.cs │ │ ├── AutoIdentifierOptions.cs │ │ └── HeadingLinkReferenceDefinition.cs │ ├── AutoLinks │ │ ├── AutoLinkExtension.cs │ │ ├── AutoLinkOptions.cs │ │ └── AutoLinkParser.cs │ ├── Bootstrap │ │ └── BootstrapExtension.cs │ ├── Citations │ │ └── CitationExtension.cs │ ├── CustomContainers │ │ ├── CustomContainer.cs │ │ ├── CustomContainerExtension.cs │ │ ├── CustomContainerInline.cs │ │ ├── CustomContainerParser.cs │ │ ├── HtmlCustomContainerInlineRenderer.cs │ │ └── HtmlCustomContainerRenderer.cs │ ├── DefinitionLists │ │ ├── DefinitionItem.cs │ │ ├── DefinitionList.cs │ │ ├── DefinitionListExtension.cs │ │ ├── DefinitionListParser.cs │ │ ├── DefinitionTerm.cs │ │ └── HtmlDefinitionListRenderer.cs │ ├── Diagrams │ │ └── DiagramExtension.cs │ ├── Emoji │ │ ├── EmojiExtension.cs │ │ ├── EmojiInline.cs │ │ ├── EmojiMapping.cs │ │ └── EmojiParser.cs │ ├── EmphasisExtras │ │ ├── EmphasisExtraExtension.cs │ │ └── EmphasisExtraOptions.cs │ ├── Figures │ │ ├── Figure.cs │ │ ├── FigureBlockParser.cs │ │ ├── FigureCaption.cs │ │ ├── FigureExtension.cs │ │ ├── HtmlFigureCaptionRenderer.cs │ │ └── HtmlFigureRenderer.cs │ ├── Footers │ │ ├── FooterBlock.cs │ │ ├── FooterBlockParser.cs │ │ ├── FooterExtension.cs │ │ └── HtmlFooterRenderer.cs │ ├── Footnotes │ │ ├── Footnote.cs │ │ ├── FootnoteExtension.cs │ │ ├── FootnoteGroup.cs │ │ ├── FootnoteLink.cs │ │ ├── FootnoteLinkReferenceDefinition.cs │ │ ├── FootnoteParser.cs │ │ ├── HtmlFootnoteGroupRenderer.cs │ │ └── HtmlFootnoteLinkRenderer.cs │ ├── GenericAttributes │ │ ├── GenericAttributesExtension.cs │ │ └── GenericAttributesParser.cs │ ├── Globalization │ │ └── GlobalizationExtension.cs │ ├── Hardlines │ │ └── SoftlineBreakAsHardlineExtension.cs │ ├── JiraLinks │ │ ├── JiraLink.cs │ │ ├── JiraLinkExtension.cs │ │ ├── JiraLinkInlineParser.cs │ │ ├── JiraLinkOptions.cs │ │ └── NormalizeJiraLinksRenderer.cs │ ├── ListExtras │ │ ├── ListExtraExtension.cs │ │ └── ListExtraItemParser.cs │ ├── Mathematics │ │ ├── HtmlMathBlockRenderer.cs │ │ ├── HtmlMathInlineRenderer.cs │ │ ├── MathBlock.cs │ │ ├── MathBlockParser.cs │ │ ├── MathExtension.cs │ │ ├── MathInline.cs │ │ └── MathInlineParser.cs │ ├── MediaLinks │ │ ├── HostProviderBuilder.cs │ │ ├── IHostProvider.cs │ │ ├── MediaLinkExtension.cs │ │ └── MediaOptions.cs │ ├── NoRefLinks │ │ └── NoFollowLinksExtension.cs │ ├── NonAsciiNoEscape │ │ └── NonAsciiNoEscapeExtension.cs │ ├── PragmaLines │ │ └── PragmaLineExtension.cs │ ├── ReferralLinks │ │ └── ReferralLinksExtension.cs │ ├── SelfPipeline │ │ └── SelfPipelineExtension.cs │ ├── SmartyPants │ │ ├── HtmlSmartyPantRenderer.cs │ │ ├── SmartyPant.cs │ │ ├── SmartyPantOptions.cs │ │ ├── SmartyPantType.cs │ │ ├── SmartyPantsExtension.cs │ │ └── SmartyPantsInlineParser.cs │ ├── Tables │ │ ├── GridTableExtension.cs │ │ ├── GridTableParser.cs │ │ ├── GridTableState.cs │ │ ├── HtmlTableRenderer.cs │ │ ├── PipeTableBlockParser.cs │ │ ├── PipeTableDelimiterInline.cs │ │ ├── PipeTableExtension.cs │ │ ├── PipeTableOptions.cs │ │ ├── PipeTableParser.cs │ │ ├── Table.cs │ │ ├── TableCell.cs │ │ ├── TableColumnAlign.cs │ │ ├── TableColumnDefinition.cs │ │ ├── TableHelper.cs │ │ └── TableRow.cs │ ├── TaskLists │ │ ├── HtmlTaskListRenderer.cs │ │ ├── NormalizeTaskListRenderer.cs │ │ ├── TaskList.cs │ │ ├── TaskListExtension.cs │ │ └── TaskListInlineParser.cs │ ├── TextRenderer │ │ └── ConfigureNewLineExtension.cs │ └── Yaml │ │ ├── YamlFrontMatterBlock.cs │ │ ├── YamlFrontMatterExtension.cs │ │ ├── YamlFrontMatterHtmlRenderer.cs │ │ ├── YamlFrontMatterParser.cs │ │ └── YamlFrontMatterRoundtripRenderer.cs ├── Globals.cs ├── Helpers │ ├── BlockWrapper.cs │ ├── CharHelper.cs │ ├── CharNormalizer.cs │ ├── CharacterMap.cs │ ├── CompactPrefixTree.cs │ ├── CustomArrayPool.cs │ ├── DefaultObjectCache.cs │ ├── EntityHelper.cs │ ├── FastStringWriter.cs │ ├── HexConverter.cs │ ├── HtmlHelper.cs │ ├── ICharIterator.cs │ ├── LazySubstring.cs │ ├── LineReader.cs │ ├── LinkHelper.cs │ ├── Newline.cs │ ├── ObjectCache.cs │ ├── OrderedList.cs │ ├── StringBuilderCache.cs │ ├── StringBuilderExtensions.cs │ ├── StringLine.cs │ ├── StringLineGroup.cs │ ├── StringSlice.cs │ ├── ThrowHelper.cs │ ├── TransformedStringCache.cs │ ├── UnicodeUtility.cs │ └── ValueStringBuilder.cs ├── IMarkdownExtension.cs ├── Markdig.csproj ├── Markdig.targets ├── Markdown.cs ├── MarkdownExtensions.cs ├── MarkdownParserContext.cs ├── MarkdownPipeline.cs ├── MarkdownPipelineBuilder.cs ├── Parsers │ ├── BlockParser.cs │ ├── BlockParserList.cs │ ├── BlockProcessor.cs │ ├── BlockState.cs │ ├── BlockStateExtensions.cs │ ├── FencedBlockParserBase.cs │ ├── FencedCodeBlockParser.cs │ ├── HeadingBlockParser.cs │ ├── HtmlBlockParser.cs │ ├── IAttributesParseable.cs │ ├── IBlockParser.cs │ ├── IInlineParser.cs │ ├── IMarkdownParser.cs │ ├── IPostInlineProcessor.cs │ ├── IndentedCodeBlockParser.cs │ ├── InlineParser.cs │ ├── InlineParserList.cs │ ├── InlineProcessor.cs │ ├── Inlines │ │ ├── AutolinkInlineParser.cs │ │ ├── CodeInlineParser.cs │ │ ├── EmphasisDescriptor.cs │ │ ├── EmphasisInlineParser.cs │ │ ├── EscapeInlineParser.cs │ │ ├── HtmlEntityParser.cs │ │ ├── LineBreakInlineParser.cs │ │ ├── LinkInlineParser.cs │ │ └── LiteralInlineParser.cs │ ├── ListBlockParser.cs │ ├── ListInfo.cs │ ├── ListItemParser.cs │ ├── MarkdownParser.cs │ ├── NumberedListItemParser.cs │ ├── OrderedListItemParser.cs │ ├── ParagraphBlockParser.cs │ ├── ParserBase.cs │ ├── ParserList.cs │ ├── QuoteBlockParser.cs │ ├── ThematicBreakParser.cs │ └── UnorderedListItemParser.cs ├── Polyfills │ ├── Ascii.cs │ ├── ConcurrentQueue.cs │ ├── EncodingExtensions.cs │ ├── FrozenCollections.cs │ ├── IndexOfHelpers.cs │ ├── NullableAttributes.cs │ ├── SearchValues.cs │ ├── SpanExtensions.cs │ └── Unsafe.cs ├── Renderers │ ├── Html │ │ ├── CodeBlockRenderer.cs │ │ ├── HeadingRenderer.cs │ │ ├── HtmlAttributes.cs │ │ ├── HtmlBlockRenderer.cs │ │ ├── HtmlObjectRenderer.cs │ │ ├── Inlines │ │ │ ├── AutolinkInlineRenderer.cs │ │ │ ├── CodeInlineRenderer.cs │ │ │ ├── DelimiterInlineRenderer.cs │ │ │ ├── EmphasisInlineRenderer.cs │ │ │ ├── HtmlEntityInlineRenderer.cs │ │ │ ├── HtmlInlineRenderer.cs │ │ │ ├── LineBreakInlineRenderer.cs │ │ │ ├── LinkInlineRenderer.cs │ │ │ └── LiteralInlineRenderer.cs │ │ ├── ListRenderer.cs │ │ ├── ParagraphRenderer.cs │ │ ├── QuoteBlockRenderer.cs │ │ └── ThematicBreakRenderer.cs │ ├── HtmlRenderer.cs │ ├── IMarkdownObjectRenderer.cs │ ├── IMarkdownRenderer.cs │ ├── MarkdownObjectRenderer.cs │ ├── Normalize │ │ ├── CodeBlockRenderer.cs │ │ ├── HeadingRenderer.cs │ │ ├── HtmlBlockRenderer.cs │ │ ├── Inlines │ │ │ ├── AutolinkInlineRenderer.cs │ │ │ ├── CodeInlineRenderer.cs │ │ │ ├── DelimiterInlineRenderer.cs │ │ │ ├── EmphasisInlineRenderer.cs │ │ │ ├── LineBreakInlineRenderer.cs │ │ │ ├── LinkInlineRenderer.cs │ │ │ ├── LiteralInlineRenderer.cs │ │ │ ├── NormalizeHtmlEntityInlineRenderer.cs │ │ │ └── NormalizeHtmlInlineRenderer.cs │ │ ├── LinkReferenceDefinitionGroupRenderer.cs │ │ ├── LinkReferenceDefinitionRenderer.cs │ │ ├── ListRenderer.cs │ │ ├── NormalizeObjectRenderer.cs │ │ ├── NormalizeOptions.cs │ │ ├── NormalizeRenderer.cs │ │ ├── ParagraphRenderer.cs │ │ ├── QuoteBlockRenderer.cs │ │ └── ThematicBreakRenderer.cs │ ├── ObjectRendererCollection.cs │ ├── RendererBase.cs │ ├── Roundtrip │ │ ├── CodeBlockRenderer.cs │ │ ├── EmptyBlockRenderer.cs │ │ ├── HeadingRenderer.cs │ │ ├── HtmlBlockRenderer.cs │ │ ├── Inlines │ │ │ ├── AutolinkInlineRenderer.cs │ │ │ ├── CodeInlineRenderer.cs │ │ │ ├── DelimiterInlineRenderer.cs │ │ │ ├── EmphasisInlineRenderer.cs │ │ │ ├── LineBreakInlineRenderer.cs │ │ │ ├── LinkInlineRenderer.cs │ │ │ ├── LiteralInlineRenderer.cs │ │ │ ├── RoundtripHtmlEntityInlineRenderer.cs │ │ │ └── RoundtripHtmlInlineRenderer.cs │ │ ├── LinkReferenceDefinitionGroupRenderer.cs │ │ ├── LinkReferenceDefinitionRenderer.cs │ │ ├── ListRenderer.cs │ │ ├── ParagraphRenderer.cs │ │ ├── QuoteBlockRenderer.cs │ │ ├── RoundtripObjectRenderer.cs │ │ ├── RoundtripRenderer.cs │ │ └── ThematicBreakRenderer.cs │ └── TextRendererBase.cs ├── Roundtrip.md ├── SkipLocalsInit.cs ├── Syntax │ ├── BlankLineBlock.cs │ ├── Block.cs │ ├── BlockExtensions.cs │ ├── CharIteratorHelper.cs │ ├── CodeBlock.cs │ ├── ContainerBlock.cs │ ├── FencedCodeBlock.cs │ ├── HeadingBlock.cs │ ├── HtmlBlock.cs │ ├── HtmlBlockType.cs │ ├── IBlock.cs │ ├── IFencedBlock.cs │ ├── IMarkdownObject.cs │ ├── Inlines │ │ ├── AutolinkInline.cs │ │ ├── CodeInline.cs │ │ ├── ContainerInline.cs │ │ ├── DelimiterInline.cs │ │ ├── DelimiterType.cs │ │ ├── EmphasisDelimiterInline.cs │ │ ├── EmphasisInline.cs │ │ ├── HtmlEntityInline.cs │ │ ├── HtmlInline.cs │ │ ├── IInline.cs │ │ ├── Inline.cs │ │ ├── LeafInline.cs │ │ ├── LineBreakInline.cs │ │ ├── LinkDelimiterInline.cs │ │ ├── LinkInline.cs │ │ └── LiteralInline.cs │ ├── LeafBlock.cs │ ├── LinkReferenceDefinition.cs │ ├── LinkReferenceDefinitionExtensions.cs │ ├── LinkReferenceDefinitionGroup.cs │ ├── ListBlock.cs │ ├── ListItemBlock.cs │ ├── MarkdownDocument.cs │ ├── MarkdownObject.cs │ ├── MarkdownObjectExtensions.cs │ ├── NoBlocksFoundBlock.cs │ ├── ParagraphBlock.cs │ ├── QuoteBlock.cs │ ├── SourceSpan.cs │ └── ThematicBreakBlock.cs └── readme.md ├── SpecFileGen ├── Program.cs └── SpecFileGen.csproj ├── UnicodeNormDApp ├── Program.cs └── UnicodeNormDApp.csproj ├── dotnet-releaser.toml ├── global.json ├── markdig.sln ├── markdig.sln.DotSettings └── mdtoc ├── Program.cs └── mdtoc.csproj /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome:http://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | # All Files 7 | [*] 8 | charset = utf-8 9 | indent_style = space 10 | indent_size = 4 11 | insert_final_newline = false 12 | trim_trailing_whitespace = true 13 | 14 | # Solution Files 15 | [*.sln] 16 | indent_style = tab 17 | 18 | # XML Project Files 19 | [*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] 20 | indent_size = 2 21 | 22 | # Configuration Files 23 | [*.{json,xml,yml,config,props,targets,nuspec,resx,ruleset}] 24 | indent_size = 2 25 | 26 | # Markdown Files 27 | [*.md] 28 | trim_trailing_whitespace = false 29 | 30 | # Web Files 31 | [*.{htm,html,js,ts,css,scss,less}] 32 | indent_size = 2 33 | insert_final_newline = true 34 | 35 | # Bash Files 36 | [*.sh] 37 | end_of_line = lf 38 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.cs text=auto diff=csharp 3 | *.sln text=auto eol=crlf -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [xoofx] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - 'doc/**' 7 | - 'img/**' 8 | - 'changelog.md' 9 | - 'readme.md' 10 | pull_request: 11 | 12 | jobs: 13 | build: 14 | uses: xoofx/.github/.github/workflows/dotnet.yml@main 15 | with: 16 | dotnet-version: | 17 | 6.0 18 | 8.0 19 | 9.0 20 | secrets: 21 | NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/nuget_org_only.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /img/markdig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/img/markdig.png -------------------------------------------------------------------------------- /img/markdig128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/img/markdig128.png -------------------------------------------------------------------------------- /img/markdig64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/img/markdig64.png -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2019, Alexandre Mutel 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification 5 | , are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /src/Markdig.Benchmarks/CommonMarkLib.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Runtime.InteropServices; 6 | using System.Text; 7 | 8 | namespace Testamina.Markdig.Benchmarks; 9 | 10 | public static class CommonMarkLib 11 | { 12 | public static string ToHtml(string text) 13 | { 14 | unsafe 15 | { 16 | var textAsArray = Encoding.UTF8.GetBytes(text); 17 | 18 | fixed (void* ptext = textAsArray) 19 | { 20 | var ptr = (byte*)cmark_markdown_to_html(new IntPtr(ptext), text.Length); 21 | int length = 0; 22 | while (ptr[length] != 0) 23 | { 24 | length++; 25 | } 26 | var buffer = new byte[length]; 27 | Marshal.Copy(new IntPtr(ptr), buffer, 0, length); 28 | var result = Encoding.UTF8.GetString(buffer); 29 | Marshal.FreeHGlobal(new IntPtr(ptr)); 30 | return result; 31 | } 32 | } 33 | } 34 | 35 | // char *cmark_markdown_to_html(const char *text, size_t len, int options); 36 | [DllImport("cmark", CallingConvention = CallingConvention.Cdecl)] 37 | private static extern IntPtr cmark_markdown_to_html(IntPtr charBuffer, int len, int options = 0); 38 | } -------------------------------------------------------------------------------- /src/Markdig.Benchmarks/Markdig.Benchmarks.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | Exe 5 | true 6 | false 7 | enable 8 | 9 | 10 | 11 | 12 | 13 | 14 | cmark.dll 15 | PreserveNewest 16 | 17 | 18 | PreserveNewest 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Markdig.Benchmarks/cmark.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/src/Markdig.Benchmarks/cmark.dll -------------------------------------------------------------------------------- /src/Markdig.Signed/Markdig.Signed.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Markdig.Signed 4 | key.snk 5 | true 6 | 7 | 8 | 9 | %(RecursiveDir)%(Filename)%(Extension) 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Markdig.Signed/key.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/src/Markdig.Signed/key.snk -------------------------------------------------------------------------------- /src/Markdig.Tests/ArgumentOutOfRangeException.md: -------------------------------------------------------------------------------- 1 | (## 2 | 3 | - +- 4 | 5 | : Z`e* 6 | 7 | - + 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/Markdig.Tests/GlobalUsings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | global using Assert = NUnit.Framework.Legacy.ClassicAssert; -------------------------------------------------------------------------------- /src/Markdig.Tests/Markdig.Tests.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | True -------------------------------------------------------------------------------- /src/Markdig.Tests/NormalizeSpecs/Headings.md: -------------------------------------------------------------------------------- 1 | # Headings 2 | 3 | ```````````````````````````````` example 4 | # Heading 1 5 | 6 | ## Heading 2 7 | 8 | ### Heading 3 9 | 10 | #### Heading 4 11 | 12 | ##### Heading 5 13 | 14 | ###### Heading 6 15 | . 16 | # Heading 1 17 | 18 | ## Heading 2 19 | 20 | ### Heading 3 21 | 22 | #### Heading 4 23 | 24 | ##### Heading 5 25 | 26 | ###### Heading 6 27 | ```````````````````````````````` 28 | 29 | ```````````````````````````````` example 30 | ###### Heading 31 | 32 | Text after two newlines 33 | . 34 | ###### Heading 35 | 36 | Text after two newlines 37 | ```````````````````````````````` 38 | 39 | ```````````````````````````````` example 40 | Heading 41 | ======= 42 | 43 | Text after two newlines 1 44 | . 45 | # Heading 46 | 47 | Text after two newlines 1 48 | ```````````````````````````````` 49 | -------------------------------------------------------------------------------- /src/Markdig.Tests/PlainTextSpecs/SamplePlainText.generated.cs: -------------------------------------------------------------------------------- 1 | 2 | // -------------------------------- 3 | // Sample 4 | // -------------------------------- 5 | 6 | using System; 7 | using NUnit.Framework; 8 | 9 | namespace Markdig.Tests.Specs.PlainText.Sample 10 | { 11 | [TestFixture] 12 | public class TestSamplePlainTextSpec 13 | { 14 | // # Sample plain text spec 15 | // 16 | // Emphasis and anchors are stripped. A newline is ensured. 17 | [Test] 18 | public void SamplePlainTextSpec_Example001() 19 | { 20 | // Example 1 21 | // Section: Sample plain text spec 22 | // 23 | // The following Markdown: 24 | // *Hello*, [world](http://example.com)! 25 | // 26 | // Should be rendered as: 27 | // Hello, world! 28 | // 29 | 30 | TestPlainText.TestSpec("*Hello*, [world](http://example.com)!", "Hello, world!\n", "", context: "Example 1\nSection Sample plain text spec\n"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Markdig.Tests/PlainTextSpecs/SamplePlainText.md: -------------------------------------------------------------------------------- 1 | # Sample plain text spec 2 | 3 | Emphasis and anchors are stripped. A newline is ensured. 4 | 5 | ```````````````````````````````` example 6 | *Hello*, [world](http://example.com)! 7 | . 8 | Hello, world! 9 | 10 | ```````````````````````````````` -------------------------------------------------------------------------------- /src/Markdig.Tests/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Tests; 6 | 7 | class Program 8 | { 9 | public static void Main(string[] args) 10 | { 11 | Console.WriteLine("Run NUnit tests runner with this"); 12 | // Uncomment the following line to debug a specific tests more easily 13 | //var tests = new Specs.CommonMarkV_0_29.TestLeafBlocksSetextHeadings(); 14 | //tests.LeafBlocksSetextHeadings_Example063(); 15 | } 16 | } -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/Inlines/TestAutoLinkInline.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using static Markdig.Tests.TestRoundtrip; 3 | 4 | namespace Markdig.Tests.RoundtripSpecs.Inlines 5 | { 6 | [TestFixture] 7 | public class TestAutoLinkInline 8 | { 9 | [TestCase("")] 10 | [TestCase(" ")] 11 | [TestCase(" ")] 12 | [TestCase(" ")] 13 | [TestCase("")] 14 | [TestCase(" ")] 15 | [TestCase(" ")] 16 | [TestCase(" ")] 17 | [TestCase("p http://a p")] 18 | public void Test(string value) 19 | { 20 | RoundTrip(value); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/Inlines/TestHtmlInline.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using static Markdig.Tests.TestRoundtrip; 3 | 4 | namespace Markdig.Tests.RoundtripSpecs.Inlines 5 | { 6 | [TestFixture] 7 | public class TestHtmlInline 8 | { 9 | [TestCase("f")] 10 | [TestCase(" f")] 11 | [TestCase("f ")] 12 | [TestCase(" f ")] 13 | [TestCase("p")] 14 | [TestCase("")] 15 | [TestCase(" ")] 16 | [TestCase(" ")] 17 | [TestCase(" ")] 18 | [TestCase("\t")] 19 | [TestCase(" \t")] 20 | [TestCase("\t ")] 21 | [TestCase(" \t ")] 22 | public void Test(string value) 23 | { 24 | RoundTrip(value); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/Inlines/TestImageInline.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using static Markdig.Tests.TestRoundtrip; 3 | 4 | namespace Markdig.Tests.RoundtripSpecs.Inlines 5 | { 6 | [TestFixture] 7 | public class TestImageInline 8 | { 9 | [TestCase("![](a)")] 10 | [TestCase(" ![](a)")] 11 | [TestCase("![](a) ")] 12 | [TestCase(" ![](a) ")] 13 | [TestCase(" ![description](http://example.com)")] 14 | public void Test(string value) 15 | { 16 | RoundTrip(value); 17 | } 18 | 19 | [TestCase("paragraph ![description](http://example.com)")] 20 | public void TestParagraph(string value) 21 | { 22 | RoundTrip(value); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/Inlines/TestLineBreakInline.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using static Markdig.Tests.TestRoundtrip; 3 | 4 | namespace Markdig.Tests.RoundtripSpecs.Inlines 5 | { 6 | [TestFixture] 7 | public class TestLineBreakInline 8 | { 9 | [TestCase("p\n")] 10 | [TestCase("p\r\n")] 11 | [TestCase("p\r")] 12 | [TestCase("[]() ![]() `` ` ` ` ` ![]() ![]()")] 13 | public void Test(string value) 14 | { 15 | RoundTrip(value); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/Inlines/TestNullCharacterInline.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Renderers.Roundtrip; 2 | using Markdig.Syntax; 3 | using NUnit.Framework; 4 | using System.IO; 5 | 6 | namespace Markdig.Tests.RoundtripSpecs.Inlines 7 | { 8 | [TestFixture] 9 | public class TestNullCharacterInline 10 | { 11 | [TestCase("\0", "\uFFFD")] 12 | [TestCase("\0p", "\uFFFDp")] 13 | [TestCase("p\0", "p\uFFFD")] 14 | [TestCase("p\0p", "p\uFFFDp")] 15 | [TestCase("p\0\0p", "p\uFFFD\uFFFDp")] // I promise you, this was not intentional 16 | public void Test(string value, string expected) 17 | { 18 | RoundTrip(value, expected); 19 | } 20 | 21 | // this method is copied intentionally to ensure all other tests 22 | // do not unintentionally use the expected parameter 23 | private static void RoundTrip(string markdown, string expected) 24 | { 25 | var pipelineBuilder = new MarkdownPipelineBuilder(); 26 | pipelineBuilder.EnableTrackTrivia(); 27 | MarkdownPipeline pipeline = pipelineBuilder.Build(); 28 | MarkdownDocument markdownDocument = Markdown.Parse(markdown, pipeline); 29 | var sw = new StringWriter(); 30 | var rr = new RoundtripRenderer(sw); 31 | 32 | rr.Write(markdownDocument); 33 | 34 | Assert.AreEqual(expected, sw.ToString()); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestAtxHeading.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestAtxHeading 7 | { 8 | [TestCase("# h")] 9 | [TestCase("# h ")] 10 | [TestCase("# h\n#h")] 11 | [TestCase("# h\n #h")] 12 | [TestCase("# h\n # h")] 13 | [TestCase("# h\n # h ")] 14 | [TestCase(" # h \n # h ")] 15 | public void Test(string value) 16 | { 17 | RoundTrip(value); 18 | } 19 | 20 | [TestCase("\n# h\n\np")] 21 | [TestCase("\n# h\n\np\n")] 22 | [TestCase("\n# h\n\np\n\n")] 23 | [TestCase("\n\n# h\n\np\n\n")] 24 | [TestCase("\n\n# h\np\n\n")] 25 | [TestCase("\n\n# h\np\n\n")] 26 | public void TestParagraph(string value) 27 | { 28 | RoundTrip(value); 29 | } 30 | 31 | [TestCase("\n# h")] 32 | [TestCase("\n# h\n")] 33 | [TestCase("\n# h\r")] 34 | [TestCase("\n# h\r\n")] 35 | 36 | [TestCase("\r# h")] 37 | [TestCase("\r# h\n")] 38 | [TestCase("\r# h\r")] 39 | [TestCase("\r# h\r\n")] 40 | 41 | [TestCase("\r\n# h")] 42 | [TestCase("\r\n# h\n")] 43 | [TestCase("\r\n# h\r")] 44 | [TestCase("\r\n# h\r\n")] 45 | 46 | [TestCase("# h\n\n ")] 47 | [TestCase("# h\n\n ")] 48 | [TestCase("# h\n\n ")] 49 | public void TestNewline(string value) 50 | { 51 | RoundTrip(value); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestHtmlBlock.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestHtmlBlock 7 | { 8 | [TestCase("
")] 9 | [TestCase("
\n")] 10 | [TestCase("
\n\n")] 11 | [TestCase("
\n\n# h")] 12 | [TestCase("p\n\n
\n")] 13 | [TestCase("
\n\n# h")] 14 | public void Test(string value) 15 | { 16 | RoundTrip(value); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestNoBlocksFoundBlock.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestNoBlocksFoundBlock 7 | { 8 | [TestCase("\r")] 9 | [TestCase("\n")] 10 | [TestCase("\r\n")] 11 | [TestCase("\t")] 12 | [TestCase("\v")] 13 | [TestCase("\f")] 14 | [TestCase(" ")] 15 | [TestCase(" ")] 16 | [TestCase(" ")] 17 | public void Test(string value) 18 | { 19 | RoundTrip(value); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestSetextHeading.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestSetextHeading 7 | { 8 | [TestCase("h1\n===")] //3 9 | [TestCase("h1\n ===")] //3 10 | [TestCase("h1\n ===")] //3 11 | [TestCase("h1\n ===")] //3 12 | [TestCase("h1\n=== ")] //3 13 | [TestCase("h1 \n===")] //3 14 | [TestCase("h1\\\n===")] //3 15 | [TestCase("h1\n === ")] //3 16 | [TestCase("h1\nh1 l2\n===")] //3 17 | [TestCase("h1\n====")] // 4 18 | [TestCase("h1\n ====")] // 4 19 | [TestCase("h1\n==== ")] // 4 20 | [TestCase("h1\n ==== ")] // 4 21 | [TestCase("h1\n===\nh1\n===")] //3 22 | [TestCase("\\>h1\n===")] //3 23 | public void Test(string value) 24 | { 25 | RoundTrip(value); 26 | } 27 | 28 | [TestCase("h1\r===")] 29 | [TestCase("h1\n===")] 30 | [TestCase("h1\r\n===")] 31 | 32 | [TestCase("h1\r===\r")] 33 | [TestCase("h1\n===\r")] 34 | [TestCase("h1\r\n===\r")] 35 | 36 | [TestCase("h1\r===\n")] 37 | [TestCase("h1\n===\n")] 38 | [TestCase("h1\r\n===\n")] 39 | 40 | [TestCase("h1\r===\r\n")] 41 | [TestCase("h1\n===\r\n")] 42 | [TestCase("h1\r\n===\r\n")] 43 | 44 | [TestCase("h1\n===\n\n\nh2---\n\n")] 45 | [TestCase("h1\r===\r\r\rh2---\r\r")] 46 | [TestCase("h1\r\n===\r\n\r\n\r\nh2---\r\n\r\n")] 47 | public void TestNewline(string value) 48 | { 49 | RoundTrip(value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestThematicBreak.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestThematicBreak 7 | { 8 | [TestCase("---")] 9 | [TestCase(" ---")] 10 | [TestCase(" ---")] 11 | [TestCase(" ---")] 12 | [TestCase("--- ")] 13 | [TestCase(" --- ")] 14 | [TestCase(" --- ")] 15 | [TestCase(" --- ")] 16 | [TestCase("- - -")] 17 | [TestCase(" - - -")] 18 | [TestCase(" - - - ")] 19 | [TestCase("-- -")] 20 | [TestCase("---\n")] 21 | [TestCase("---\n\n")] 22 | [TestCase("---\np")] 23 | [TestCase("---\n\np")] 24 | [TestCase("---\n# h")] 25 | [TestCase("p\n\n---")] 26 | // Note: "p\n---" is parsed as setext heading 27 | public void Test(string value) 28 | { 29 | RoundTrip(value); 30 | } 31 | 32 | [TestCase("\n---")] 33 | [TestCase("\r---")] 34 | [TestCase("\r\n---")] 35 | 36 | [TestCase("\n---\n")] 37 | [TestCase("\r---\n")] 38 | [TestCase("\r\n---\n")] 39 | 40 | [TestCase("\n---\r")] 41 | [TestCase("\r---\r")] 42 | [TestCase("\r\n---\r")] 43 | 44 | [TestCase("\n---\r\n")] 45 | [TestCase("\r---\r\n")] 46 | [TestCase("\r\n---\r\n")] 47 | public void TestNewline(string value) 48 | { 49 | RoundTrip(value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/Markdig.Tests/RoundtripSpecs/TestYamlFrontMatterBlock.cs: -------------------------------------------------------------------------------- 1 | using static Markdig.Tests.TestRoundtrip; 2 | 3 | namespace Markdig.Tests.RoundtripSpecs; 4 | 5 | [TestFixture] 6 | public class TestYamlFrontMatterBlock 7 | { 8 | [TestCase("---\nkey1: value1\nkey2: value2\n---\n\nContent\n")] 9 | [TestCase("No front matter")] 10 | [TestCase("Looks like front matter but actually is not\n---\nkey1: value1\nkey2: value2\n---")] 11 | public void FrontMatterBlockIsPreserved(string value) 12 | { 13 | RoundTrip(value); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/BootstrapSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | Adds support for outputting bootstrap ready tags: 4 | 5 | ## Bootstrap 6 | 7 | Adds bootstrap `.table` class to ``: 8 | 9 | ```````````````````````````````` example 10 | Name | Value 11 | -----| ----- 12 | Abc | 16 13 | . 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
NameValue
Abc16
28 | ```````````````````````````````` 29 | 30 | Adds bootstrap `.blockquote` class to `
`: 31 | 32 | ```````````````````````````````` example 33 | > This is a blockquote 34 | . 35 |
36 |

This is a blockquote

37 |
38 | ```````````````````````````````` 39 | 40 | Adds bootstrap `.figure` class to `
` and `.figure-caption` to `
` 41 | 42 | ```````````````````````````````` example 43 | ^^^ 44 | This is a text in a caption 45 | ^^^ This is the caption 46 | . 47 |
48 |

This is a text in a caption

49 |
This is the caption
50 |
51 | ```````````````````````````````` 52 | 53 | Adds the `.img-fluid` class to all image links `` 54 | 55 | ```````````````````````````````` example 56 | ![Image Link](/url) 57 | . 58 |

Image Link

59 | ```````````````````````````````` -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/DiagramsSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | Adds support for diagrams extension: 4 | 5 | ## Mermaid diagrams 6 | 7 | Using a fenced code block with the `mermaid` language info will output a `
` block (which is the default for other code block):
 8 | 
 9 | ```````````````````````````````` example
10 | ```mermaid
11 | graph TD;
12 |     A-->B;
13 |     A-->C;
14 |     B-->D;
15 |     C-->D;
16 | ```
17 | .
18 | 
graph TD;
19 |     A-->B;
20 |     A-->C;
21 |     B-->D;
22 |     C-->D;
23 | 
24 | ```````````````````````````````` 25 | 26 | ## nomnoml diagrams 27 | 28 | Using a fenced code block with the `nomnoml` language info will output a `
` instead of a `pre/code` block: 29 | 30 | ```````````````````````````````` example 31 | ```nomnoml 32 | [example| 33 | propertyA: Int 34 | propertyB: string 35 | | 36 | methodA() 37 | methodB() 38 | | 39 | [subA]--[subB] 40 | [subA]-:>[sub C] 41 | ] 42 | ``` 43 | . 44 |
[example| 45 | propertyA: Int 46 | propertyB: string 47 | | 48 | methodA() 49 | methodB() 50 | | 51 | [subA]--[subB] 52 | [subA]-:>[sub C] 53 | ] 54 |
55 | ```````````````````````````````` 56 | 57 | TODO: Add other text diagram languages -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/EmojiSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | This section describes the different extensions supported: 4 | 5 | ## Emoji 6 | 7 | Emoji shortcodes and smileys can be converted to their respective unicode characters: 8 | 9 | ```````````````````````````````` example 10 | This is a test with a :) and a :angry: smiley 11 | . 12 |

This is a test with a 😃 and a 😠 smiley

13 | ```````````````````````````````` 14 | 15 | An emoji needs to be preceded by a space: 16 | 17 | ```````````````````````````````` example 18 | These are not:) an emoji with a:) x:angry:x 19 | . 20 |

These are not:) an emoji with a:) x:angry:x

21 | ```````````````````````````````` 22 | 23 | Emojis can be followed by close punctuation (or any other characters): 24 | 25 | ```````````````````````````````` example 26 | We all need :), it makes us :muscle:. (and :ok_hand:). 27 | . 28 |

We all need 😃, it makes us 💪. (and 👌).

29 | ```````````````````````````````` 30 | 31 | Sentences can end with emojis: 32 | 33 | ```````````````````````````````` example 34 | This is a sentence :ok_hand: 35 | and keeps going to the next line :) 36 | . 37 |

This is a sentence 👌 38 | and keeps going to the next line 😃

39 | ```````````````````````````````` 40 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/FigureFooterAndCiteSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | The following the figure extension: 4 | 5 | ## Figures 6 | 7 | A figure can be defined by using a pattern equivalent to a fenced code block but with the character `^` 8 | 9 | ```````````````````````````````` example 10 | ^^^ 11 | This is a figure 12 | ^^^ This is a *caption* 13 | . 14 |
15 |

This is a figure

16 |
This is a caption
17 |
18 | ```````````````````````````````` 19 | 20 | ## Footers 21 | 22 | A footer equivalent to a block quote parsing but starts with double character ^^ 23 | 24 | ```````````````````````````````` example 25 | ^^ This is a footer 26 | ^^ multi-line 27 | . 28 |
This is a footer 29 | multi-line
30 | ```````````````````````````````` 31 | 32 | ## Cite 33 | 34 | A cite is working like an emphasis but using the double character "" 35 | 36 | ```````````````````````````````` example 37 | This is a ""citation of someone"" 38 | . 39 |

This is a citation of someone

40 | ```````````````````````````````` 41 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/HardlineBreakSpecs.generated.cs: -------------------------------------------------------------------------------- 1 | 2 | // -------------------------------- 3 | // Hardline Breaks 4 | // -------------------------------- 5 | 6 | using System; 7 | using NUnit.Framework; 8 | 9 | namespace Markdig.Tests.Specs.HardlineBreaks 10 | { 11 | [TestFixture] 12 | public class TestExtensionsHardlineBreak 13 | { 14 | // # Extensions 15 | // 16 | // This section describes the different extensions supported: 17 | // 18 | // ## Hardline break 19 | // 20 | // When this extension is used, a new line in a paragraph block will result in a hardline break `
`: 21 | [Test] 22 | public void ExtensionsHardlineBreak_Example001() 23 | { 24 | // Example 1 25 | // Section: Extensions / Hardline break 26 | // 27 | // The following Markdown: 28 | // This is a paragraph 29 | // with a break inside 30 | // 31 | // Should be rendered as: 32 | //

This is a paragraph
33 | // with a break inside

34 | 35 | TestParser.TestSpec("This is a paragraph\nwith a break inside", "

This is a paragraph
\nwith a break inside

", "hardlinebreak|advanced+hardlinebreak", context: "Example 1\nSection Extensions / Hardline break\n"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/HardlineBreakSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | This section describes the different extensions supported: 4 | 5 | ## Hardline break 6 | 7 | When this extension is used, a new line in a paragraph block will result in a hardline break `
`: 8 | 9 | ```````````````````````````````` example 10 | This is a paragraph 11 | with a break inside 12 | . 13 |

This is a paragraph
14 | with a break inside

15 | ```````````````````````````````` 16 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/NoHtmlSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | ## NoHTML 4 | 5 | The extension DisableHtml allows to disable the parsing of HTML: 6 | 7 | For inline HTML: 8 | 9 | ```````````````````````````````` example 10 | this is some text 11 | . 12 |

this is some text</td></tr>

13 | ```````````````````````````````` 14 | 15 | For Block HTML: 16 | 17 | ```````````````````````````````` example 18 |
19 | this is some text 20 |
21 | . 22 |

<div> 23 | this is some text 24 | </div>

25 | ```````````````````````````````` 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Markdig.Tests/Specs/TaskListSpecs.md: -------------------------------------------------------------------------------- 1 | # Extensions 2 | 3 | Adds support for task lists: 4 | 5 | ## TaskLists 6 | 7 | A task list item consist of `[ ]` or `[x]` or `[X]` inside a list item (ordered or unordered) 8 | 9 | ```````````````````````````````` example 10 | - [ ] Item1 11 | - [x] Item2 12 | - [ ] Item3 13 | - Item4 14 | . 15 |
    16 |
  • Item1
  • 17 |
  • Item2
  • 18 |
  • Item3
  • 19 |
  • Item4
  • 20 |
21 | ```````````````````````````````` 22 | 23 | A task is not recognized outside a list item: 24 | 25 | ```````````````````````````````` example 26 | [ ] This is not a task list 27 | . 28 |

[ ] This is not a task list

29 | ```````````````````````````````` 30 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestAutoLinks.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Extensions.AutoLinks; 2 | 3 | namespace Markdig.Tests; 4 | 5 | [TestFixture] 6 | public class TestAutoLinks 7 | { 8 | [Test] 9 | [TestCase("https://localhost", "

https://localhost

")] 10 | [TestCase("http://localhost", "

http://localhost

")] 11 | [TestCase("https://l", "

https://l

")] 12 | [TestCase("www.l", "

www.l

")] 13 | [TestCase("https://localhost:5000", "

https://localhost:5000

")] 14 | [TestCase("www.l:5000", "

www.l:5000

")] 15 | public void TestLinksWithAllowDomainWithoutPeriod(string markdown, string expected) 16 | { 17 | var pipeline = new MarkdownPipelineBuilder() 18 | .UseAutoLinks(new AutoLinkOptions { AllowDomainWithoutPeriod = true }) 19 | .Build(); 20 | var html = Markdown.ToHtml(markdown, pipeline); 21 | 22 | Assert.That(html, Is.EqualTo(expected).IgnoreWhiteSpace); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestContainerInlines.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Syntax; 2 | using Markdig.Syntax.Inlines; 3 | 4 | namespace Markdig.Tests; 5 | 6 | public class TestContainerInlines 7 | { 8 | private class MockLeafBlock : LeafBlock 9 | { 10 | public MockLeafBlock() 11 | : base(null) 12 | { 13 | 14 | } 15 | } 16 | 17 | [Test] 18 | public void CanBeAddedToLeafBlock() 19 | { 20 | var leafBlock1 = new MockLeafBlock(); 21 | 22 | var one = new ContainerInline(); 23 | Assert.Null(one.ParentBlock); 24 | 25 | leafBlock1.Inline = one; 26 | Assert.AreSame(leafBlock1, one.ParentBlock); 27 | 28 | var two = new ContainerInline(); 29 | Assert.Null(two.ParentBlock); 30 | 31 | leafBlock1.Inline = two; 32 | Assert.AreSame(leafBlock1, two.ParentBlock); 33 | Assert.Null(one.ParentBlock); 34 | 35 | var leafBlock2 = new MockLeafBlock(); 36 | Assert.Throws(() => leafBlock2.Inline = two); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestEmphasisPlus.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Tests; 9 | 10 | [TestFixture] 11 | public partial class TestEmphasisPlus 12 | { 13 | [Test] 14 | public void StrongNormal() 15 | { 16 | TestParser.TestSpec("***Strong emphasis*** normal", "

Strong emphasis normal

", ""); 17 | } 18 | 19 | [Test] 20 | public void NormalStrongNormal() 21 | { 22 | TestParser.TestSpec("normal ***Strong emphasis*** normal", "

normal Strong emphasis normal

", ""); 23 | } 24 | 25 | [Test] 26 | public void OpenEmphasisHasConvenientContentStringSlice() 27 | { 28 | var pipeline = new MarkdownPipelineBuilder().Build(); 29 | 30 | var document = Markdown.Parse("test*test", pipeline); 31 | 32 | var emphasisDelimiterLiteral = (LiteralInline)((ParagraphBlock)document.LastChild).Inline.ElementAt(1); 33 | Assert.That(emphasisDelimiterLiteral.Content.Text == "test*test"); 34 | Assert.That(emphasisDelimiterLiteral.Content.Start == 4); 35 | Assert.That(emphasisDelimiterLiteral.Content.End == 4); 36 | } 37 | } -------------------------------------------------------------------------------- /src/Markdig.Tests/TestExceptionNotThrown.cs: -------------------------------------------------------------------------------- 1 | namespace Markdig.Tests; 2 | 3 | [TestFixture] 4 | public class TestExceptionNotThrown 5 | { 6 | [Test] 7 | public void DoesNotThrowIndexOutOfRangeException1() 8 | { 9 | Assert.DoesNotThrow(() => 10 | { 11 | var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); 12 | Markdown.ToHtml("+-\n|\n+", pipeline); 13 | }); 14 | } 15 | 16 | [Test] 17 | public void DoesNotThrowIndexOutOfRangeException2() 18 | { 19 | Assert.DoesNotThrow(() => 20 | { 21 | var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); 22 | Markdown.ToHtml("+--\n|\n+0", pipeline); 23 | }); 24 | } 25 | 26 | [Test] 27 | public void DoesNotThrowIndexOutOfRangeException3() 28 | { 29 | Assert.DoesNotThrow(() => 30 | { 31 | var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); 32 | Markdown.ToHtml("+-\n|\n+\n0", pipeline); 33 | }); 34 | } 35 | 36 | [Test] 37 | public void DoesNotThrowIndexOutOfRangeException4() 38 | { 39 | Assert.DoesNotThrow(() => 40 | { 41 | var pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build(); 42 | Markdown.ToHtml("+-\n|\n+0", pipeline); 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestHtmlHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | using Markdig.Helpers; 5 | 6 | namespace Markdig.Tests; 7 | 8 | [TestFixture] 9 | public class TestHtmlHelper 10 | { 11 | [Test] 12 | public void TestParseHtmlTagSimple() 13 | { 14 | var inputTag = ""; 15 | var text = new StringSlice(inputTag); 16 | Assert.True(HtmlHelper.TryParseHtmlTag(ref text, out string outputTag)); 17 | Assert.AreEqual(inputTag, outputTag); 18 | } 19 | 20 | [Test] 21 | public void TestParseHtmlTagSimpleWithAttribute() 22 | { 23 | var inputTag = ""; 24 | var text = new StringSlice(inputTag); 25 | Assert.True(HtmlHelper.TryParseHtmlTag(ref text, out string outputTag)); 26 | Assert.AreEqual(inputTag, outputTag); 27 | } 28 | } -------------------------------------------------------------------------------- /src/Markdig.Tests/TestImageAltText.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace Markdig.Tests; 4 | 5 | [TestFixture] 6 | public class TestImageAltText 7 | { 8 | [Test] 9 | [TestCase("![](image.jpg)", "")] 10 | [TestCase("![foo](image.jpg)", "foo")] 11 | [TestCase("![][1]\n\n[1]: image.jpg", "")] 12 | [TestCase("![bar][1]\n\n[1]: image.jpg", "bar")] 13 | [TestCase("![](image.jpg 'title')", "")] 14 | [TestCase("![foo](image.jpg 'title')", "foo")] 15 | [TestCase("![][1]\n\n[1]: image.jpg 'title'", "")] 16 | [TestCase("![bar][1]\n\n[1]: image.jpg 'title'", "bar")] 17 | public void TestImageHtmlAltText(string markdown, string expectedAltText) 18 | { 19 | string html = Markdown.ToHtml(markdown); 20 | string actualAltText = Regex.Match(html, "alt=\"(.*?)\"").Groups[1].Value; 21 | Assert.AreEqual(expectedAltText, actualAltText); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestLinkRewriter.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Parsers; 2 | using Markdig.Renderers; 3 | 4 | namespace Markdig.Tests; 5 | 6 | public class TestLinkRewriter 7 | { 8 | [Test] 9 | public void ReplacesRelativeLinks() 10 | { 11 | TestSpec(s => "abc" + s, "Link: [hello](/relative.jpg)", "abc/relative.jpg"); 12 | TestSpec(s => s + "xyz", "Link: [hello](relative.jpg)", "relative.jpgxyz"); 13 | TestSpec(null, "Link: [hello](relative.jpg)", "relative.jpg"); 14 | TestSpec(null, "Link: [hello](/relative.jpg)", "/relative.jpg"); 15 | } 16 | 17 | [Test] 18 | public void ReplacesRelativeImageSources() 19 | { 20 | TestSpec(s => "abc" + s, "Image: ![alt text](/image.jpg)", "abc/image.jpg"); 21 | TestSpec(s => "abc" + s, "Image: ![alt text](image.jpg \"title\")", "abcimage.jpg"); 22 | TestSpec(null, "Image: ![alt text](/image.jpg)", "/image.jpg"); 23 | } 24 | 25 | public static void TestSpec(Func linkRewriter, string markdown, string expectedLink) 26 | { 27 | var pipeline = new MarkdownPipelineBuilder().Build(); 28 | 29 | var writer = new StringWriter(); 30 | var renderer = new HtmlRenderer(writer); 31 | renderer.LinkRewriter = linkRewriter; 32 | pipeline.Setup(renderer); 33 | 34 | var document = MarkdownParser.Parse(markdown, pipeline); 35 | renderer.Render(document); 36 | writer.Flush(); 37 | 38 | Assert.That(writer.ToString(), Contains.Substring("=\"" + expectedLink + "\"")); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Markdig.Tests/TestNewLine.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Syntax; 2 | using Markdig.Syntax.Inlines; 3 | 4 | namespace Markdig.Tests; 5 | 6 | [TestFixture] 7 | public class TestNewLine 8 | { 9 | [TestCase("a \nb", "

a
\nb

\n")] 10 | [TestCase("a\\\nb", "

a
\nb

\n")] 11 | [TestCase("a `b\nc`", "

a b c

\n")] 12 | [TestCase("# Text A\nText B\n\n## Text C", "

Text A

\n

Text B

\n

Text C

\n")] 13 | public void Test(string value, string expectedHtml) 14 | { 15 | Assert.AreEqual(expectedHtml, Markdown.ToHtml(value)); 16 | Assert.AreEqual(expectedHtml, Markdown.ToHtml(value.Replace("\n", "\r\n"))); 17 | } 18 | 19 | [Test()] 20 | public void TestEscapeLineBreak() 21 | { 22 | var input = "test\\\r\ntest1\r\n"; 23 | var doc = Markdown.Parse(input); 24 | var inlines = doc.Descendants().ToList(); 25 | Assert.AreEqual(1, inlines.Count, "Invalid number of LineBreakInline"); 26 | Assert.True(inlines[0].IsBackslash); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestOrderedList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Tests; 8 | 9 | [TestFixture] 10 | public class TestOrderedList 11 | { 12 | [Test] 13 | public void TestReplace() 14 | { 15 | var list = new OrderedList 16 | { 17 | new A(), 18 | new B(), 19 | new C(), 20 | }; 21 | 22 | // Replacing B with D. Order should now be A, D, B. 23 | var result = list.Replace(new D()); 24 | Assert.That(result, Is.True); 25 | Assert.That(list.Count, Is.EqualTo(3)); 26 | Assert.That(list[0], Is.InstanceOf
()); 27 | Assert.That(list[1], Is.InstanceOf()); 28 | Assert.That(list[2], Is.InstanceOf()); 29 | 30 | // Replacing B again should fail, as it's no longer in the list. 31 | Assert.That(list.Replace(new D()), Is.False); 32 | } 33 | 34 | #region Test fixtures 35 | private interface ITest { } 36 | private class A : ITest { } 37 | private class B : ITest { } 38 | private class C : ITest { } 39 | private class D : ITest { } 40 | #endregion 41 | } -------------------------------------------------------------------------------- /src/Markdig.Tests/TestRoundtrip.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Renderers.Roundtrip; 2 | using Markdig.Syntax; 3 | 4 | namespace Markdig.Tests; 5 | 6 | internal static class TestRoundtrip 7 | { 8 | internal static void TestSpec(string markdownText, string expected, string extensions, string context = null) 9 | { 10 | RoundTrip(markdownText, context); 11 | } 12 | 13 | internal static void RoundTrip(string markdown, string context = null) 14 | { 15 | var pipelineBuilder = new MarkdownPipelineBuilder(); 16 | pipelineBuilder.EnableTrackTrivia(); 17 | pipelineBuilder.UseYamlFrontMatter(); 18 | MarkdownPipeline pipeline = pipelineBuilder.Build(); 19 | MarkdownDocument markdownDocument = Markdown.Parse(markdown, pipeline); 20 | var sw = new StringWriter(); 21 | var nr = new RoundtripRenderer(sw); 22 | pipeline.Setup(nr); 23 | 24 | nr.Write(markdownDocument); 25 | 26 | var result = sw.ToString(); 27 | TestParser.PrintAssertExpected("", result, markdown, context); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Markdig.Tests/TestSmartyPants.cs: -------------------------------------------------------------------------------- 1 | using Markdig.Extensions.SmartyPants; 2 | 3 | namespace Markdig.Tests; 4 | 5 | public class TestSmartyPants 6 | { 7 | [Test] 8 | public void MappingCanBeReconfigured() 9 | { 10 | var options = new SmartyPantOptions(); 11 | options.Mapping[SmartyPantType.LeftAngleQuote] = "foo"; 12 | options.Mapping[SmartyPantType.RightAngleQuote] = "bar"; 13 | 14 | var pipeline = new MarkdownPipelineBuilder() 15 | .UseSmartyPants(options) 16 | .Build(); 17 | 18 | TestParser.TestSpec("<>", "

footestbar

", pipeline); 19 | } 20 | 21 | [Test] 22 | public void MappingCanBeReconfigured_HandlesRemovedMappings() 23 | { 24 | var options = new SmartyPantOptions(); 25 | options.Mapping.Remove(SmartyPantType.LeftAngleQuote); 26 | options.Mapping.Remove(SmartyPantType.RightAngleQuote); 27 | 28 | var pipeline = new MarkdownPipelineBuilder() 29 | .UseSmartyPants(options) 30 | .Build(); 31 | 32 | TestParser.TestSpec("<>", "

«test»

", pipeline); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Markdig.Tests/hang.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xoofx/markdig/682c727288defba5dfab05ccb4ef847c760d412c/src/Markdig.Tests/hang.md -------------------------------------------------------------------------------- /src/Markdig.WebApp/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.9.809.2", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/Markdig.WebApp/Markdig.WebApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | true 6 | Markdig.WebApp 7 | enable 8 | Exe 9 | Markdig.WebApp 10 | /subscriptions/b6745039-70e7-4641-994b-5457cb220e2a/resourcegroups/Default-ApplicationInsights-EastUS/providers/microsoft.insights/components/Markdig.WebApp 11 | /subscriptions/b6745039-70e7-4641-994b-5457cb220e2a/resourcegroups/Default-ApplicationInsights-EastUS/providers/microsoft.insights/components/Markdig.WebApp 12 | false 13 | 683145f2-53a7-4938-bd96-35e60ac55d95 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Markdig.WebApp/Program.cs: -------------------------------------------------------------------------------- 1 | namespace Markdig.WebApp; 2 | 3 | public class Program 4 | { 5 | public static void Main(string[] args) 6 | { 7 | CreateHostBuilder(args).Build().Run(); 8 | } 9 | 10 | public static IHostBuilder CreateHostBuilder(string[] args) => 11 | Host.CreateDefaultBuilder(args) 12 | .ConfigureWebHostDefaults(webBuilder => 13 | { 14 | webBuilder.UseStartup(); 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /src/Markdig.WebApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "Markdig.WebApp": { 4 | "commandName": "Project", 5 | "launchBrowser": true, 6 | "launchUrl": "api/to_html?text=test" 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /src/Markdig.WebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | }, 10 | "ApplicationInsights": { 11 | "InstrumentationKey": "5d12f113-76b2-41fe-a35a-db454b104bf9", 12 | "ConnectionString": "InstrumentationKey=c00ad051-d881-4dc3-b8c1-8718f1b1c0c6;IngestionEndpoint=https://westus2-0.in.applicationinsights.azure.com/" 13 | } 14 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Abbreviations/Abbreviation.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using Markdig.Helpers; 7 | using Markdig.Parsers; 8 | using Markdig.Syntax; 9 | 10 | namespace Markdig.Extensions.Abbreviations; 11 | 12 | /// 13 | /// An abbreviation object stored at the document level. See extension methods in . 14 | /// 15 | /// 16 | [DebuggerDisplay("Abbr {Label} => {Text}")] 17 | public class Abbreviation : LeafBlock 18 | { 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// The parser used to create this block. 23 | public Abbreviation(BlockParser parser) : base(parser) 24 | { 25 | } 26 | 27 | /// 28 | /// Gets or sets the label. 29 | /// 30 | public string? Label { get; set; } 31 | 32 | /// 33 | /// The text associated to this label. 34 | /// 35 | public StringSlice Text; 36 | 37 | /// 38 | /// The label span 39 | /// 40 | public SourceSpan LabelSpan; 41 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Abbreviations/AbbreviationExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.Abbreviations; 8 | 9 | /// 10 | /// Extension to allow abbreviations. 11 | /// 12 | /// 13 | public class AbbreviationExtension : IMarkdownExtension 14 | { 15 | public void Setup(MarkdownPipelineBuilder pipeline) 16 | { 17 | pipeline.BlockParsers.AddIfNotAlready(); 18 | } 19 | 20 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 21 | { 22 | if (renderer is HtmlRenderer htmlRenderer && !htmlRenderer.ObjectRenderers.Contains()) 23 | { 24 | // Must be inserted before CodeBlockRenderer 25 | htmlRenderer.ObjectRenderers.Insert(0, new HtmlAbbreviationRenderer()); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Abbreviations/AbbreviationHelper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Abbreviations; 9 | 10 | /// 11 | /// Extension methods for . 12 | /// 13 | public static class AbbreviationHelper 14 | { 15 | private static readonly object DocumentKey = typeof (Abbreviation); 16 | 17 | public static bool HasAbbreviations(this MarkdownDocument document) 18 | { 19 | return document.GetAbbreviations() != null; 20 | } 21 | 22 | public static void AddAbbreviation(this MarkdownDocument document, string label, Abbreviation abbr) 23 | { 24 | if (document is null) ThrowHelper.ArgumentNullException(nameof(document)); 25 | if (label is null) ThrowHelper.ArgumentNullException_label(); 26 | if (abbr is null) ThrowHelper.ArgumentNullException(nameof(abbr)); 27 | 28 | var map = document.GetAbbreviations(); 29 | if (map is null) 30 | { 31 | map = new Dictionary(); 32 | document.SetData(DocumentKey, map); 33 | } 34 | map[label] = abbr; 35 | } 36 | 37 | public static Dictionary? GetAbbreviations(this MarkdownDocument document) 38 | { 39 | return document.GetData(DocumentKey) as Dictionary; 40 | } 41 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Abbreviations/AbbreviationInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.Abbreviations; 9 | 10 | /// 11 | /// The inline abbreviation. 12 | /// 13 | /// 14 | [DebuggerDisplay("{Abbreviation}")] 15 | public class AbbreviationInline : LeafInline 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The abbreviation. 21 | public AbbreviationInline(Abbreviation abbreviation) 22 | { 23 | Abbreviation = abbreviation; 24 | } 25 | 26 | public Abbreviation Abbreviation { get; set; } 27 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Abbreviations/HtmlAbbreviationRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Abbreviations; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlAbbreviationRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, AbbreviationInline obj) 17 | { 18 | // HTML 19 | var abbr = obj.Abbreviation; 20 | if (renderer.EnableHtmlForInline) 21 | { 22 | renderer.Write(""); 23 | } 24 | renderer.Write(abbr.Label); 25 | if (renderer.EnableHtmlForInline) 26 | { 27 | renderer.Write(""); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Alerts/AlertBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Alerts; 9 | 10 | /// 11 | /// A block representing an alert quote block. 12 | /// 13 | public class AlertBlock : QuoteBlock 14 | { 15 | /// 16 | /// Creates a new instance of this block. 17 | /// 18 | /// 19 | public AlertBlock(StringSlice kind) : base(null) 20 | { 21 | Kind = kind; 22 | } 23 | 24 | /// 25 | /// Gets or sets the kind of the alert block (e.g `NOTE`, `TIP`, `IMPORTANT`, `WARNING`, `CAUTION`). 26 | /// 27 | public StringSlice Kind { get; set; } 28 | 29 | /// 30 | /// Gets or sets the trivia space after the kind. 31 | /// 32 | public StringSlice TriviaSpaceAfterKind { get; set; } 33 | } 34 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/Alerts/AlertExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Parsers.Inlines; 7 | using Markdig.Renderers; 8 | using Markdig.Renderers.Html; 9 | 10 | namespace Markdig.Extensions.Alerts; 11 | 12 | /// 13 | /// Extension for adding alerts to a Markdown pipeline. 14 | /// 15 | public class AlertExtension : IMarkdownExtension 16 | { 17 | /// 18 | /// Gets or sets the delegate to render the kind of the alert. 19 | /// 20 | public Action? RenderKind { get; set; } 21 | 22 | /// 23 | public void Setup(MarkdownPipelineBuilder pipeline) 24 | { 25 | var inlineParser = pipeline.InlineParsers.Find(); 26 | if (inlineParser == null) 27 | { 28 | pipeline.InlineParsers.InsertBefore(new AlertInlineParser()); 29 | } 30 | } 31 | 32 | /// 33 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 34 | { 35 | var blockRenderer = renderer.ObjectRenderers.FindExact(); 36 | if (blockRenderer == null) 37 | { 38 | renderer.ObjectRenderers.InsertBefore(new AlertBlockRenderer() 39 | { 40 | RenderKind = RenderKind ?? AlertBlockRenderer.DefaultRenderKind 41 | }); 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/AutoIdentifiers/AutoIdentifierOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.AutoIdentifiers; 6 | 7 | /// 8 | /// Options for the . 9 | /// 10 | [Flags] 11 | public enum AutoIdentifierOptions 12 | { 13 | /// 14 | /// No options: does not apply any additional formatting and/or transformations. 15 | /// 16 | None = 0, 17 | 18 | /// 19 | /// Default () 20 | /// 21 | Default = AutoLink | AllowOnlyAscii, 22 | 23 | /// 24 | /// Allows to link to a header by using the same text as the header for the link label. Default is true 25 | /// 26 | AutoLink = 1, 27 | 28 | /// 29 | /// Allows only ASCII characters in the url (HTML 5 allows to have UTF8 characters). Default is true 30 | /// 31 | AllowOnlyAscii = 2, 32 | 33 | /// 34 | /// Renders auto identifiers like GitHub. 35 | /// 36 | GitHub = 4, 37 | } 38 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/AutoIdentifiers/HeadingLinkReferenceDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Extensions.AutoIdentifiers; 8 | 9 | /// 10 | /// A link reference definition to a stored at the level. 11 | /// 12 | /// 13 | public class HeadingLinkReferenceDefinition : LinkReferenceDefinition 14 | { 15 | public HeadingLinkReferenceDefinition(HeadingBlock headling) 16 | { 17 | Heading = headling; 18 | } 19 | 20 | /// 21 | /// Gets or sets the heading related to this link reference definition. 22 | /// 23 | public HeadingBlock Heading { get; set; } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/AutoLinks/AutoLinkExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.AutoLinks; 9 | 10 | /// 11 | /// Extension to automatically create when a link url http: or mailto: is found. 12 | /// 13 | /// 14 | public class AutoLinkExtension(AutoLinkOptions? options) : IMarkdownExtension 15 | { 16 | public readonly AutoLinkOptions Options = options ?? new AutoLinkOptions(); 17 | 18 | public void Setup(MarkdownPipelineBuilder pipeline) 19 | { 20 | if (!pipeline.InlineParsers.Contains()) 21 | { 22 | // Insert the parser before any other parsers 23 | pipeline.InlineParsers.Insert(0, new AutoLinkParser(Options)); 24 | } 25 | } 26 | 27 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 28 | { 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/AutoLinks/AutoLinkOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.AutoLinks; 6 | 7 | public class AutoLinkOptions 8 | { 9 | public AutoLinkOptions() 10 | { 11 | ValidPreviousCharacters = "*_~("; 12 | } 13 | 14 | public string ValidPreviousCharacters { get; set; } 15 | 16 | /// 17 | /// Should the link open in a new window when clicked (false by default) 18 | /// 19 | public bool OpenInNewWindow { get; set; } 20 | 21 | /// 22 | /// Should a www link be prefixed with https:// instead of http:// (false by default) 23 | /// 24 | public bool UseHttpsForWWWLinks { get; set; } 25 | 26 | /// 27 | /// Should auto-linking allow a domain with no period, e.g. https://localhost (false by default) 28 | /// 29 | public bool AllowDomainWithoutPeriod { get; set; } 30 | } 31 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/CustomContainers/CustomContainerInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Extensions.CustomContainers; 8 | 9 | /// 10 | /// An inline custom container 11 | /// 12 | /// 13 | /// 14 | public class CustomContainerInline : EmphasisInline 15 | { 16 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/CustomContainers/CustomContainerParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | 7 | namespace Markdig.Extensions.CustomContainers; 8 | 9 | /// 10 | /// The block parser for a . 11 | /// 12 | /// 13 | public class CustomContainerParser : FencedBlockParserBase 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public CustomContainerParser() 19 | { 20 | OpeningCharacters = [':']; 21 | 22 | // We don't need a prefix 23 | InfoPrefix = null; 24 | } 25 | 26 | protected override CustomContainer CreateFencedBlock(BlockProcessor processor) 27 | { 28 | return new CustomContainer(this); 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/CustomContainers/HtmlCustomContainerInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.CustomContainers; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlCustomContainerInlineRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, CustomContainerInline obj) 17 | { 18 | renderer.Write("'); 19 | renderer.WriteChildren(obj); 20 | renderer.Write(""); 21 | } 22 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/CustomContainers/HtmlCustomContainerRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.CustomContainers; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlCustomContainerRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, CustomContainer obj) 17 | { 18 | renderer.EnsureLine(); 19 | if (renderer.EnableHtmlForBlock) 20 | { 21 | renderer.Write("'); 22 | } 23 | // We don't escape a CustomContainer 24 | renderer.WriteChildren(obj); 25 | if (renderer.EnableHtmlForBlock) 26 | { 27 | renderer.WriteLine("
"); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/DefinitionLists/DefinitionItem.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.DefinitionLists; 9 | 10 | /// 11 | /// A definition item contains zero to multiple 12 | /// and definitions (any ) 13 | /// 14 | /// 15 | public class DefinitionItem : ContainerBlock 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | /// The parser used to create this block. 21 | public DefinitionItem(BlockParser parser) : base(parser) 22 | { 23 | } 24 | 25 | /// 26 | /// Gets or sets the opening character for this definition item (either `:` or `~`) 27 | /// 28 | public char OpeningCharacter { get; set; } 29 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/DefinitionLists/DefinitionList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.DefinitionLists; 9 | 10 | /// 11 | /// A definition list contains children. 12 | /// 13 | /// 14 | public class DefinitionList : ContainerBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public DefinitionList(BlockParser parser) : base(parser) 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/DefinitionLists/DefinitionListExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.DefinitionLists; 8 | 9 | /// 10 | /// Extension to allow definition lists 11 | /// 12 | /// 13 | public class DefinitionListExtension : IMarkdownExtension 14 | { 15 | public void Setup(MarkdownPipelineBuilder pipeline) 16 | { 17 | if (!pipeline.BlockParsers.Contains()) 18 | { 19 | // Insert the parser before any other parsers 20 | pipeline.BlockParsers.Insert(0, new DefinitionListParser()); 21 | } 22 | } 23 | 24 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 25 | { 26 | if (renderer is HtmlRenderer htmlRenderer) 27 | { 28 | if (!htmlRenderer.ObjectRenderers.Contains()) 29 | { 30 | htmlRenderer.ObjectRenderers.Insert(0, new HtmlDefinitionListRenderer()); 31 | } 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/DefinitionLists/DefinitionTerm.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.DefinitionLists; 9 | 10 | /// 11 | /// A definition term contains a single line with the term to define. 12 | /// 13 | /// 14 | public class DefinitionTerm : LeafBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public DefinitionTerm(BlockParser parser) : base(parser) 21 | { 22 | ProcessInlines = true; 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Diagrams/DiagramExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Diagrams; 9 | 10 | /// 11 | /// Extension to allow diagrams. 12 | /// 13 | /// 14 | public class DiagramExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | } 19 | 20 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 21 | { 22 | if (renderer is HtmlRenderer htmlRenderer) 23 | { 24 | var codeRenderer = htmlRenderer.ObjectRenderers.FindExact()!; 25 | codeRenderer.BlockMapping["mermaid"] = "pre"; 26 | codeRenderer.BlocksAsDiv.Add("nomnoml"); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/Emoji/EmojiExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.Emoji; 8 | 9 | /// 10 | /// Extension to allow emoji shortcodes and smileys replacement. 11 | /// 12 | /// 13 | public class EmojiExtension : IMarkdownExtension 14 | { 15 | public EmojiExtension(EmojiMapping emojiMapping) 16 | { 17 | EmojiMapping = emojiMapping; 18 | } 19 | 20 | public EmojiMapping EmojiMapping { get; } 21 | 22 | public void Setup(MarkdownPipelineBuilder pipeline) 23 | { 24 | if (!pipeline.InlineParsers.Contains()) 25 | { 26 | // Insert the parser before any other parsers 27 | pipeline.InlineParsers.Insert(0, new EmojiParser(EmojiMapping)); 28 | } 29 | } 30 | 31 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 32 | { 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Emoji/EmojiInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.Emoji; 9 | 10 | /// 11 | /// An emoji inline. 12 | /// 13 | /// 14 | public class EmojiInline : LiteralInline 15 | { 16 | // Inherit from LiteralInline so that rendering is already handled by default 17 | 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | public EmojiInline() 22 | { 23 | } 24 | 25 | /// 26 | /// Initializes a new instance of the class. 27 | /// 28 | /// The content. 29 | public EmojiInline(string content) 30 | { 31 | Content = new StringSlice(content); 32 | } 33 | 34 | /// 35 | /// Gets or sets the original match string (either an emoji shortcode or a text smiley) 36 | /// 37 | public string? Match { get; set; } 38 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/EmphasisExtras/EmphasisExtraOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.EmphasisExtras; 6 | 7 | /// 8 | /// Options for enabling support for extra emphasis. 9 | /// 10 | [Flags] 11 | public enum EmphasisExtraOptions 12 | { 13 | /// 14 | /// Allows all extra emphasis (default). 15 | /// 16 | Default = Strikethrough | Subscript | Superscript | Inserted | Marked, 17 | 18 | /// 19 | /// A text that can be strikethrough using the double character ~~ 20 | /// 21 | Strikethrough = 1, 22 | 23 | /// 24 | /// A text that can be rendered as a subscript using the character ~ 25 | /// 26 | Subscript = 2, 27 | 28 | /// 29 | /// A text that can be rendered as a superscript using the character ^ 30 | /// 31 | Superscript = 4, 32 | 33 | /// 34 | /// A text that can be rendered as inserted using the double character ++ 35 | /// 36 | Inserted = 8, 37 | 38 | /// 39 | /// A text that can be rendered as marked using the double character == 40 | /// 41 | Marked = 16, 42 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Figures/Figure.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Figures; 9 | 10 | /// 11 | /// Defines a figure container. 12 | /// 13 | /// 14 | public class Figure : ContainerBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public Figure(BlockParser parser) : base(parser) 21 | { 22 | } 23 | 24 | /// 25 | /// Gets or sets the opening character count used to open this figure code block. 26 | /// 27 | public int OpeningCharacterCount { get; set; } 28 | 29 | /// 30 | /// Gets or sets the opening character used to open and close this figure code block. 31 | /// 32 | public char OpeningCharacter { get; set; } 33 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Figures/FigureCaption.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Figures; 9 | 10 | /// 11 | /// Defines a figure caption. 12 | /// 13 | /// 14 | public class FigureCaption : LeafBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public FigureCaption(BlockParser parser) : base(parser) 21 | { 22 | ProcessInlines = true; 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Figures/FigureExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Extensions.Footers; 6 | using Markdig.Renderers; 7 | 8 | namespace Markdig.Extensions.Figures; 9 | 10 | /// 11 | /// Extension to allow usage of figures and figure captions. 12 | /// 13 | /// 14 | public class FigureExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | if (!pipeline.BlockParsers.Contains()) 19 | { 20 | // The Figure extension must come before the Footer extension 21 | if (pipeline.BlockParsers.Contains()) 22 | { 23 | pipeline.BlockParsers.InsertBefore(new FigureBlockParser()); 24 | } 25 | else 26 | { 27 | pipeline.BlockParsers.Insert(0, new FigureBlockParser()); 28 | } 29 | } 30 | } 31 | 32 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 33 | { 34 | if (renderer is HtmlRenderer htmlRenderer) 35 | { 36 | htmlRenderer.ObjectRenderers.AddIfNotAlready(); 37 | htmlRenderer.ObjectRenderers.AddIfNotAlready(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Figures/HtmlFigureCaptionRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Figures; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlFigureCaptionRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, FigureCaption obj) 17 | { 18 | renderer.EnsureLine(); 19 | renderer.Write("'); 20 | renderer.WriteLeafInline(obj); 21 | renderer.WriteLine("
"); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Figures/HtmlFigureRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Figures; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlFigureRenderer : HtmlObjectRenderer
15 | { 16 | protected override void Write(HtmlRenderer renderer, Figure obj) 17 | { 18 | renderer.EnsureLine(); 19 | renderer.Write(""); 20 | renderer.WriteChildren(obj); 21 | renderer.WriteLine("
"); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footers/FooterBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Footers; 9 | 10 | /// 11 | /// A block element for a footer. 12 | /// 13 | /// 14 | public class FooterBlock : ContainerBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public FooterBlock(BlockParser parser) : base(parser) 21 | { 22 | } 23 | 24 | /// 25 | /// Gets or sets the opening character used to match this footer (by default it is ^) 26 | /// 27 | public char OpeningCharacter { get; set; } 28 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footers/FooterExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Extensions.Figures; 6 | using Markdig.Renderers; 7 | 8 | namespace Markdig.Extensions.Footers; 9 | 10 | /// 11 | /// Extension that provides footer. 12 | /// 13 | /// 14 | public class FooterExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | if (!pipeline.BlockParsers.Contains()) 19 | { 20 | // The Figure extension must come before the Footer extension 21 | if (pipeline.BlockParsers.Contains()) 22 | { 23 | pipeline.BlockParsers.InsertAfter(new FooterBlockParser()); 24 | } 25 | else 26 | { 27 | pipeline.BlockParsers.Insert(0, new FooterBlockParser()); 28 | } 29 | } 30 | } 31 | 32 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 33 | { 34 | if (renderer is HtmlRenderer htmlRenderer) 35 | { 36 | htmlRenderer.ObjectRenderers.AddIfNotAlready(new HtmlFooterBlockRenderer()); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footers/HtmlFooterRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Footers; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlFooterBlockRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, FooterBlock footer) 17 | { 18 | renderer.EnsureLine(); 19 | renderer.Write(""); 20 | var implicitParagraph = renderer.ImplicitParagraph; 21 | renderer.ImplicitParagraph = true; 22 | renderer.WriteChildren(footer); 23 | renderer.ImplicitParagraph = implicitParagraph; 24 | renderer.WriteLine(""); 25 | } 26 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/Footnote.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Footnotes; 9 | 10 | /// 11 | /// A block for a footnote. 12 | /// 13 | /// 14 | public class Footnote : ContainerBlock 15 | { 16 | public Footnote(BlockParser parser) : base(parser) 17 | { 18 | Order = -1; 19 | } 20 | 21 | /// 22 | /// Gets or sets the label used by this footnote. 23 | /// 24 | public string? Label { get; set; } 25 | 26 | /// 27 | /// Gets or sets the order of this footnote (determined by the order of the in the document) 28 | /// 29 | public int Order { get; set; } 30 | 31 | /// 32 | /// Gets the links referencing this footnote. 33 | /// 34 | public List Links { get; } = new (); 35 | 36 | /// 37 | /// The label span 38 | /// 39 | public SourceSpan LabelSpan; 40 | 41 | internal bool IsLastLineEmpty { get; set; } 42 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/FootnoteExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.Footnotes; 8 | 9 | /// 10 | /// Extension to allow footnotes. 11 | /// 12 | /// 13 | public class FootnoteExtension : IMarkdownExtension 14 | { 15 | public void Setup(MarkdownPipelineBuilder pipeline) 16 | { 17 | if (!pipeline.BlockParsers.Contains()) 18 | { 19 | // Insert the parser before any other parsers 20 | pipeline.BlockParsers.Insert(0, new FootnoteParser()); 21 | } 22 | } 23 | 24 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 25 | { 26 | if (renderer is HtmlRenderer htmlRenderer) 27 | { 28 | htmlRenderer.ObjectRenderers.AddIfNotAlready(new HtmlFootnoteGroupRenderer()); 29 | htmlRenderer.ObjectRenderers.AddIfNotAlready(new HtmlFootnoteLinkRenderer()); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/FootnoteGroup.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Footnotes; 9 | 10 | /// 11 | /// A block that contains all the footnotes at the end of a . 12 | /// 13 | /// 14 | public class FootnoteGroup : ContainerBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser used to create this block. 20 | public FootnoteGroup(BlockParser parser) : base(parser) 21 | { 22 | } 23 | 24 | internal int CurrentOrder { get; set; } 25 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/FootnoteLink.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Extensions.Footnotes; 8 | 9 | /// 10 | /// A inline link to a . 11 | /// 12 | /// 13 | public class FootnoteLink : Inline 14 | { 15 | public FootnoteLink(Footnote footnote) 16 | { 17 | Footnote = footnote; 18 | } 19 | 20 | /// 21 | /// Gets or sets a value indicating whether this instance is back link (from a footnote to the link) 22 | /// 23 | public bool IsBackLink { get; set; } 24 | 25 | /// 26 | /// Gets or sets the global index number of this link. 27 | /// 28 | public int Index { get; set; } 29 | 30 | /// 31 | /// Gets or sets the footnote this link refers to. 32 | /// 33 | public Footnote Footnote { get; set; } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/FootnoteLinkReferenceDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Extensions.Footnotes; 8 | 9 | /// 10 | /// A link reference definition stored at the level. 11 | /// 12 | /// 13 | public class FootnoteLinkReferenceDefinition : LinkReferenceDefinition 14 | { 15 | public FootnoteLinkReferenceDefinition(Footnote footnote) 16 | { 17 | Footnote = footnote; 18 | } 19 | 20 | /// 21 | /// Gets or sets the footnote related to this link reference definition. 22 | /// 23 | public Footnote Footnote { get; set; } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Footnotes/HtmlFootnoteLinkRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Footnotes; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlFootnoteLinkRenderer : HtmlObjectRenderer 15 | { 16 | public HtmlFootnoteLinkRenderer() 17 | { 18 | BackLinkString = "↩"; 19 | FootnoteLinkClass = "footnote-ref"; 20 | FootnoteBackLinkClass = "footnote-back-ref"; 21 | } 22 | public string BackLinkString { get; set; } 23 | 24 | public string FootnoteLinkClass { get; set; } 25 | 26 | public string FootnoteBackLinkClass { get; set; } 27 | 28 | protected override void Write(HtmlRenderer renderer, FootnoteLink link) 29 | { 30 | var order = link.Footnote.Order; 31 | renderer.Write(link.IsBackLink 32 | ? $"
{BackLinkString}" 33 | : $"{order}"); 34 | } 35 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Hardlines/SoftlineBreakAsHardlineExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers.Inlines; 6 | using Markdig.Renderers; 7 | 8 | namespace Markdig.Extensions.Hardlines; 9 | 10 | /// 11 | /// Extension to generate hardline break for softline breaks. 12 | /// 13 | /// 14 | public class SoftlineBreakAsHardlineExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | // Simply modify the LineBreakInlineParser 19 | // TODO: We might want more options (like pandoc) 20 | var parser = pipeline.InlineParsers.Find(); 21 | if (parser != null) 22 | { 23 | parser.EnableSoftAsHard = true; 24 | } 25 | } 26 | 27 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 28 | { 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/JiraLinks/JiraLink.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using Markdig.Helpers; 7 | using Markdig.Syntax.Inlines; 8 | 9 | namespace Markdig.Extensions.JiraLinks; 10 | 11 | /// 12 | /// Model for a JIRA link item 13 | /// 14 | [DebuggerDisplay("{ProjectKey}-{Issue}")] 15 | public class JiraLink : LinkInline 16 | { 17 | public JiraLink() 18 | { 19 | IsClosed = true; 20 | } 21 | 22 | /// 23 | /// JIRA Project Key 24 | /// 25 | public StringSlice ProjectKey { get; set; } 26 | 27 | /// 28 | /// JIRA Issue Number 29 | /// 30 | public StringSlice Issue { get; set; } 31 | } 32 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/JiraLinks/JiraLinkOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Extensions.JiraLinks; 8 | 9 | /// 10 | /// Available options for replacing JIRA links 11 | /// 12 | public class JiraLinkOptions 13 | { 14 | /// 15 | /// The base Url (e.g. `https://mycompany.atlassian.net`) 16 | /// 17 | public string BaseUrl { get; set; } 18 | 19 | /// 20 | /// The base path after the base url (default is `/browse`) 21 | /// 22 | public string BasePath { get; set; } 23 | 24 | /// 25 | /// Should the link open in a new window when clicked 26 | /// 27 | public bool OpenInNewWindow { get; set; } 28 | 29 | public JiraLinkOptions(string baseUrl) 30 | { 31 | OpenInNewWindow = true; //default 32 | BaseUrl = baseUrl; 33 | BasePath = "/browse"; 34 | } 35 | 36 | /// 37 | /// Gets the full url composed of the and with no trailing `/` 38 | /// 39 | public virtual string GetUrl() 40 | { 41 | var url = new ValueStringBuilder(stackalloc char[ValueStringBuilder.StackallocThreshold]); 42 | url.Append(BaseUrl.AsSpan().TrimEnd('/')); 43 | url.Append('/'); 44 | url.Append(BasePath.AsSpan().Trim('/')); 45 | return url.ToString(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/JiraLinks/NormalizeJiraLinksRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers.Normalize; 6 | 7 | namespace Markdig.Extensions.JiraLinks; 8 | 9 | public class NormalizeJiraLinksRenderer : NormalizeObjectRenderer 10 | { 11 | protected override void Write(NormalizeRenderer renderer, JiraLink obj) 12 | { 13 | renderer.Write(obj.ProjectKey); 14 | renderer.Write("-"); 15 | renderer.Write(obj.Issue); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/ListExtras/ListExtraExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Renderers; 7 | 8 | namespace Markdig.Extensions.ListExtras; 9 | 10 | /// 11 | /// Extension for adding new type of list items (a., A., i., I.) 12 | /// 13 | /// 14 | public class ListExtraExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | var parser = pipeline.BlockParsers.Find(); 19 | if (parser != null) 20 | { 21 | parser.ItemParsers.AddIfNotAlready(); 22 | } 23 | } 24 | 25 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 26 | { 27 | } 28 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Mathematics/HtmlMathBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Mathematics; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlMathBlockRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, MathBlock obj) 17 | { 18 | renderer.EnsureLine(); 19 | if (renderer.EnableHtmlForBlock) 20 | { 21 | renderer.Write(""); 22 | renderer.WriteLine("\\["); 23 | } 24 | 25 | renderer.WriteLeafRawLines(obj, true, renderer.EnableHtmlEscape); 26 | 27 | if (renderer.EnableHtmlForBlock) 28 | { 29 | renderer.Write("\\]"); 30 | renderer.WriteLine(""); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Mathematics/HtmlMathInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Mathematics; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlMathInlineRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, MathInline obj) 17 | { 18 | if (renderer.EnableHtmlForInline) 19 | { 20 | renderer.Write("\\("); 21 | } 22 | 23 | if (renderer.EnableHtmlEscape) 24 | { 25 | renderer.WriteEscape(ref obj.Content); 26 | } 27 | else 28 | { 29 | renderer.Write(ref obj.Content); 30 | } 31 | 32 | if (renderer.EnableHtmlForInline) 33 | { 34 | renderer.Write("\\)"); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Mathematics/MathBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Mathematics; 9 | 10 | /// 11 | /// A math block. 12 | /// 13 | /// 14 | public class MathBlock : FencedCodeBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser. 20 | public MathBlock(BlockParser parser) : base(parser) 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Mathematics/MathInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.Mathematics; 9 | 10 | /// 11 | /// A math inline element. 12 | /// 13 | /// 14 | public class MathInline : LeafInline 15 | { 16 | /// 17 | /// Gets or sets the delimiter character used by this code inline. 18 | /// 19 | public char Delimiter { get; set; } 20 | 21 | /// 22 | /// Gets or sets the delimiter count. 23 | /// 24 | public int DelimiterCount { get; set; } 25 | 26 | /// 27 | /// The content as a . 28 | /// 29 | public StringSlice Content; 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/MediaLinks/IHostProvider.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics.CodeAnalysis; 6 | 7 | namespace Markdig.Extensions.MediaLinks; 8 | 9 | /// 10 | /// Provides url for media links. 11 | /// 12 | public interface IHostProvider 13 | { 14 | /// 15 | /// "class" attribute of generated iframe. 16 | /// 17 | string? Class { get; } 18 | 19 | /// 20 | /// Generate url for iframe. 21 | /// 22 | /// Input media uri. 23 | /// if is a schema relative uri, i.e. uri starts with "//". 24 | /// Generated url for iframe. 25 | /// 26 | bool TryHandle(Uri mediaUri, bool isSchemaRelative, [NotNullWhen(true)] out string? iframeUrl); 27 | 28 | /// 29 | /// Should the generated iframe has allowfullscreen attribute. 30 | /// 31 | /// 32 | /// Should be false for audio embedding. 33 | /// 34 | bool AllowFullScreen { get; } 35 | } 36 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/NoRefLinks/NoFollowLinksExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Extensions.ReferralLinks; 6 | using Markdig.Renderers; 7 | 8 | namespace Markdig.Extensions.NoRefLinks; 9 | 10 | /// 11 | /// Extension to automatically render rel=nofollow to all links in an HTML output. 12 | /// 13 | [Obsolete("Use ReferralLinksExtension class instead")] 14 | public class NoFollowLinksExtension : IMarkdownExtension 15 | { 16 | private ReferralLinksExtension _referralLinksExtension; 17 | 18 | public NoFollowLinksExtension() 19 | { 20 | _referralLinksExtension = new ReferralLinksExtension(["nofollow"]); 21 | } 22 | 23 | public void Setup(MarkdownPipelineBuilder pipeline) 24 | { 25 | _referralLinksExtension.Setup(pipeline); 26 | } 27 | 28 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 29 | { 30 | _referralLinksExtension.Setup(pipeline, renderer); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/NonAsciiNoEscape/NonAsciiNoEscapeExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.NonAsciiNoEscape; 8 | 9 | /// 10 | /// Extension that will disable URI escape with % characters for non-US-ASCII characters in order to workaround a bug under IE/Edge with local file links containing non US-ASCII chars. DO NOT USE OTHERWISE. 11 | /// 12 | public class NonAsciiNoEscapeExtension : IMarkdownExtension 13 | { 14 | public void Setup(MarkdownPipelineBuilder pipeline) 15 | { 16 | } 17 | 18 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 19 | { 20 | if (renderer is HtmlRenderer htmlRenderer) 21 | { 22 | htmlRenderer.UseNonAsciiNoEscape = true; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/ReferralLinks/ReferralLinksExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Linq; 6 | 7 | using Markdig.Renderers; 8 | using Markdig.Renderers.Html.Inlines; 9 | 10 | namespace Markdig.Extensions.ReferralLinks; 11 | 12 | public class ReferralLinksExtension : IMarkdownExtension 13 | { 14 | public ReferralLinksExtension(string[] rels) 15 | { 16 | Rels = rels?.ToList() ?? throw new ArgumentNullException(nameof(rels)); 17 | } 18 | 19 | public List Rels { get; } 20 | 21 | public void Setup(MarkdownPipelineBuilder pipeline) 22 | { 23 | } 24 | 25 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 26 | { 27 | string relString = string.Join(" ", Rels.Where(r => !string.IsNullOrEmpty(r))); 28 | 29 | var linkRenderer = renderer.ObjectRenderers.Find(); 30 | if (linkRenderer != null) 31 | { 32 | linkRenderer.Rel = relString; 33 | } 34 | 35 | var autolinkRenderer = renderer.ObjectRenderers.Find(); 36 | if (autolinkRenderer != null) 37 | { 38 | autolinkRenderer.Rel = relString; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/SmartyPants/HtmlSmartyPantRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.SmartyPants; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlSmartyPantRenderer : HtmlObjectRenderer 15 | { 16 | private static readonly SmartyPantOptions DefaultOptions = new SmartyPantOptions(); 17 | 18 | private readonly SmartyPantOptions options; 19 | 20 | /// 21 | /// Initializes a new instance of the class. 22 | /// 23 | /// The options. 24 | /// 25 | public HtmlSmartyPantRenderer(SmartyPantOptions? options) 26 | { 27 | this.options = options ?? throw new ArgumentNullException(nameof(options)); 28 | } 29 | 30 | protected override void Write(HtmlRenderer renderer, SmartyPant obj) 31 | { 32 | if (!options.Mapping.TryGetValue(obj.Type, out string? text)) 33 | { 34 | DefaultOptions.Mapping.TryGetValue(obj.Type, out text); 35 | } 36 | renderer.Write(text); 37 | } 38 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/SmartyPants/SmartyPantOptions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.SmartyPants; 6 | 7 | /// 8 | /// The options used for . 9 | /// 10 | public class SmartyPantOptions 11 | { 12 | /// 13 | /// Initializes a new instance of the class. 14 | /// 15 | public SmartyPantOptions() 16 | { 17 | Mapping = new Dictionary() 18 | { 19 | {SmartyPantType.Quote, "'"}, 20 | {SmartyPantType.DoubleQuote, "\""}, 21 | {SmartyPantType.LeftQuote, "‘"}, 22 | {SmartyPantType.RightQuote, "’"}, 23 | {SmartyPantType.LeftDoubleQuote, "“"}, 24 | {SmartyPantType.RightDoubleQuote, "”"}, 25 | {SmartyPantType.LeftAngleQuote, "«"}, 26 | {SmartyPantType.RightAngleQuote, "»"}, 27 | {SmartyPantType.Ellipsis, "…"}, 28 | {SmartyPantType.Dash2, "–"}, 29 | {SmartyPantType.Dash3, "—"}, 30 | }; 31 | } 32 | 33 | /// 34 | /// Gets the mapping between a and its textual representation 35 | /// (usually an HTML entity). 36 | /// 37 | public Dictionary Mapping { get; } 38 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Tables/GridTableExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.Tables; 8 | 9 | /// 10 | /// Extension that allows to use grid tables. 11 | /// 12 | /// 13 | public class GridTableExtension : IMarkdownExtension 14 | { 15 | public void Setup(MarkdownPipelineBuilder pipeline) 16 | { 17 | if (!pipeline.BlockParsers.Contains()) 18 | { 19 | pipeline.BlockParsers.Insert(0, new GridTableParser()); 20 | } 21 | } 22 | 23 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 24 | { 25 | if (renderer is HtmlRenderer htmlRenderer && !htmlRenderer.ObjectRenderers.Contains()) 26 | { 27 | htmlRenderer.ObjectRenderers.Add(new HtmlTableRenderer()); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Tables/PipeTableDelimiterInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.Tables; 9 | 10 | /// 11 | /// The delimiter used to separate the columns of a pipe table. 12 | /// 13 | /// 14 | public class PipeTableDelimiterInline : DelimiterInline 15 | { 16 | public PipeTableDelimiterInline(InlineParser parser) : base(parser) 17 | { 18 | } 19 | 20 | /// 21 | /// Gets or sets the index of line where this delimiter was found relative to the current block. 22 | /// 23 | public int LocalLineIndex { get; set; } 24 | 25 | public override string ToLiteral() 26 | { 27 | return "|"; 28 | } 29 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Tables/TableColumnAlign.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.Tables; 6 | 7 | /// 8 | /// Defines the alignment of a column 9 | /// 10 | public enum TableColumnAlign 11 | { 12 | /// 13 | /// Align the column to the left 14 | /// 15 | Left, 16 | 17 | /// 18 | /// Align the column to the center 19 | /// 20 | Center, 21 | 22 | /// 23 | /// Align the column to the right 24 | /// 25 | Right, 26 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Tables/TableColumnDefinition.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Extensions.Tables; 6 | 7 | /// 8 | /// Defines a column. 9 | /// 10 | public class TableColumnDefinition 11 | { 12 | /// 13 | /// Gets or sets the width (in percentage) of this column. A value of 0 is unspecified. 14 | /// 15 | public float Width { get; set; } 16 | 17 | /// 18 | /// Gets or sets the column alignment. 19 | /// 20 | public TableColumnAlign? Alignment { get; set; } 21 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Tables/TableRow.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Extensions.Tables; 8 | 9 | /// 10 | /// Defines a row in a , contains , parent is . 11 | /// 12 | /// 13 | public class TableRow : ContainerBlock 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | public TableRow() : base(null) 19 | { 20 | } 21 | 22 | /// 23 | /// Gets or sets a value indicating whether this instance is header row. 24 | /// 25 | public bool IsHeader { get; set; } 26 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/TaskLists/HtmlTaskListRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.TaskLists; 9 | 10 | /// 11 | /// A HTML renderer for a . 12 | /// 13 | /// 14 | public class HtmlTaskListRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, TaskList obj) 17 | { 18 | if (renderer.EnableHtmlForInline) 19 | { 20 | renderer.Write(""); 26 | } 27 | else 28 | { 29 | renderer.Write('['); 30 | renderer.Write(obj.Checked ? "x" : " "); 31 | renderer.Write(']'); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/TaskLists/NormalizeTaskListRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers.Normalize; 6 | 7 | namespace Markdig.Extensions.TaskLists; 8 | 9 | public class NormalizeTaskListRenderer : NormalizeObjectRenderer 10 | { 11 | protected override void Write(NormalizeRenderer renderer, TaskList obj) 12 | { 13 | renderer.Write("["); 14 | renderer.Write(obj.Checked ? "X" : " "); 15 | renderer.Write("]"); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/TaskLists/TaskList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Extensions.TaskLists; 9 | 10 | /// 11 | /// An inline for TaskList. 12 | /// 13 | [DebuggerDisplay("TaskList {Checked}")] 14 | public class TaskList : LeafInline 15 | { 16 | public bool Checked { get; set; } 17 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/TaskLists/TaskListExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers.Inlines; 6 | using Markdig.Renderers; 7 | using Markdig.Renderers.Normalize; 8 | 9 | namespace Markdig.Extensions.TaskLists; 10 | 11 | /// 12 | /// Extension to enable TaskList. 13 | /// 14 | public class TaskListExtension : IMarkdownExtension 15 | { 16 | public void Setup(MarkdownPipelineBuilder pipeline) 17 | { 18 | if (!pipeline.InlineParsers.Contains()) 19 | { 20 | // Insert the parser after the code span parser 21 | pipeline.InlineParsers.InsertBefore(new TaskListInlineParser()); 22 | } 23 | } 24 | 25 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 26 | { 27 | if (renderer is HtmlRenderer htmlRenderer) 28 | { 29 | htmlRenderer.ObjectRenderers.AddIfNotAlready(); 30 | } 31 | 32 | if (renderer is NormalizeRenderer normalizeRenderer) 33 | { 34 | normalizeRenderer.ObjectRenderers.AddIfNotAlready(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/TextRenderer/ConfigureNewLineExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig.Extensions.TextRenderer; 8 | 9 | /// 10 | /// Extension that allows setting line-endings for any IMarkdownRenderer 11 | /// that inherits from 12 | /// 13 | /// 14 | public class ConfigureNewLineExtension : IMarkdownExtension 15 | { 16 | private readonly string newLine; 17 | 18 | public ConfigureNewLineExtension(string newLine) 19 | { 20 | this.newLine = newLine; 21 | } 22 | 23 | public void Setup(MarkdownPipelineBuilder pipeline) 24 | { 25 | } 26 | 27 | public void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer) 28 | { 29 | if (renderer is TextRendererBase textRenderer) 30 | { 31 | textRenderer.Writer.NewLine = newLine; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Markdig/Extensions/Yaml/YamlFrontMatterBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Extensions.Yaml; 9 | 10 | /// 11 | /// A YAML frontmatter block. 12 | /// 13 | /// 14 | public class YamlFrontMatterBlock : CodeBlock 15 | { 16 | /// 17 | /// Initializes a new instance of the class. 18 | /// 19 | /// The parser. 20 | public YamlFrontMatterBlock(BlockParser parser) : base(parser) 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Yaml/YamlFrontMatterHtmlRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Html; 7 | 8 | namespace Markdig.Extensions.Yaml; 9 | 10 | /// 11 | /// Empty renderer for a 12 | /// 13 | /// 14 | public class YamlFrontMatterHtmlRenderer : HtmlObjectRenderer 15 | { 16 | protected override void Write(HtmlRenderer renderer, YamlFrontMatterBlock obj) 17 | { 18 | } 19 | } -------------------------------------------------------------------------------- /src/Markdig/Extensions/Yaml/YamlFrontMatterRoundtripRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | using Markdig.Renderers.Roundtrip; 7 | 8 | namespace Markdig.Extensions.Yaml; 9 | 10 | public class YamlFrontMatterRoundtripRenderer : MarkdownObjectRenderer 11 | { 12 | private readonly CodeBlockRenderer _codeBlockRenderer; 13 | 14 | public YamlFrontMatterRoundtripRenderer() 15 | { 16 | _codeBlockRenderer = new CodeBlockRenderer(); 17 | } 18 | 19 | protected override void Write(RoundtripRenderer renderer, YamlFrontMatterBlock obj) 20 | { 21 | renderer.Writer.WriteLine("---"); 22 | _codeBlockRenderer.Write(renderer, obj); 23 | renderer.Writer.WriteLine("---"); 24 | } 25 | } -------------------------------------------------------------------------------- /src/Markdig/Globals.cs: -------------------------------------------------------------------------------- 1 | global using System; 2 | global using System.Collections.Frozen; 3 | global using System.Collections.Generic; -------------------------------------------------------------------------------- /src/Markdig/Helpers/BlockWrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Helpers; 8 | 9 | // Used to avoid the overhead of type covariance checks 10 | internal readonly struct BlockWrapper(Block block) : IEquatable 11 | { 12 | public readonly Block Block = block; 13 | 14 | public static implicit operator Block(BlockWrapper wrapper) => wrapper.Block; 15 | 16 | public static implicit operator BlockWrapper(Block block) => new BlockWrapper(block); 17 | 18 | public bool Equals(BlockWrapper other) => ReferenceEquals(Block, other.Block); 19 | 20 | public override bool Equals(object? obj) => Block.Equals(obj); 21 | 22 | public override int GetHashCode() => Block.GetHashCode(); 23 | } 24 | -------------------------------------------------------------------------------- /src/Markdig/Helpers/DefaultObjectCache.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Helpers; 6 | 7 | /// 8 | /// A default object cache that expect the type {T} to provide a parameter less constructor 9 | /// 10 | /// The type of item to cache 11 | /// 12 | public abstract class DefaultObjectCache : ObjectCache where T : class, new() 13 | { 14 | protected override T NewInstance() 15 | { 16 | return new T(); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Helpers/HexConverter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace Markdig.Helpers; 8 | 9 | // Based on https://github.com/dotnet/runtime/blob/main/src/libraries/Common/src/System/HexConverter.cs 10 | internal static class HexConverter 11 | { 12 | public enum Casing : uint 13 | { 14 | Upper = 0, 15 | Lower = 0x2020U, 16 | } 17 | 18 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 19 | public static void ToCharsBuffer(byte value, Span buffer, int startingIndex = 0, Casing casing = Casing.Upper) 20 | { 21 | uint difference = (((uint)value & 0xF0U) << 4) + ((uint)value & 0x0FU) - 0x8989U; 22 | uint packedResult = ((((uint)(-(int)difference) & 0x7070U) >> 4) + difference + 0xB9B9U) | (uint)casing; 23 | 24 | buffer[startingIndex + 1] = (char)(packedResult & 0xFF); 25 | buffer[startingIndex] = (char)(packedResult >> 8); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Markdig/Helpers/LazySubstring.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | 7 | namespace Markdig.Helpers; 8 | 9 | internal struct LazySubstring 10 | { 11 | private string _text; 12 | public int Offset; 13 | public int Length; 14 | 15 | public LazySubstring(string text) 16 | { 17 | _text = text; 18 | Offset = 0; 19 | Length = text.Length; 20 | } 21 | 22 | public LazySubstring(string text, int offset, int length) 23 | { 24 | Debug.Assert((ulong)offset + (ulong)length <= (ulong)text.Length, $"{offset}-{length} in {text}"); 25 | _text = text; 26 | Offset = offset; 27 | Length = length; 28 | } 29 | 30 | public ReadOnlySpan AsSpan() => _text.AsSpan(Offset, Length); 31 | 32 | public override string ToString() 33 | { 34 | if (Offset != 0 || Length != _text.Length) 35 | { 36 | _text = _text.Substring(Offset, Length); 37 | Offset = 0; 38 | } 39 | 40 | return _text; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Markdig/Helpers/Newline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Helpers; 6 | 7 | /// 8 | /// Represents a character or set of characters that represent a separation 9 | /// between two lines of text 10 | /// 11 | public enum NewLine : byte 12 | { 13 | // Values have the length encoded in last 2 bits 14 | None = 0, 15 | CarriageReturn = 4 | 1, 16 | LineFeed = 8 | 1, 17 | CarriageReturnLineFeed = 16 | 2 18 | } 19 | 20 | public static class NewLineExtensions 21 | { 22 | public static string AsString(this NewLine newLine) => newLine switch 23 | { 24 | NewLine.CarriageReturnLineFeed => "\r\n", 25 | NewLine.LineFeed => "\n", 26 | NewLine.CarriageReturn => "\r", 27 | _ => string.Empty, 28 | }; 29 | 30 | public static int Length(this NewLine newLine) => (int)newLine & 3; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /src/Markdig/Helpers/StringBuilderCache.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Text; 6 | 7 | namespace Markdig.Helpers; 8 | 9 | public static class StringBuilderCache 10 | { 11 | /// 12 | /// A StringBuilder that can be used locally in a method body only. 13 | /// 14 | [ThreadStatic] 15 | private static StringBuilder? local; 16 | 17 | /// 18 | /// Provides a string builder that can only be used locally in a method. This StringBuilder MUST not be stored. 19 | /// 20 | /// 21 | public static StringBuilder Local() 22 | { 23 | var sb = local ??= new StringBuilder(); 24 | if (sb.Length != 0) 25 | { 26 | sb.Length = 0; 27 | } 28 | return sb; 29 | } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Helpers/StringBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Text; 6 | 7 | namespace Markdig.Helpers; 8 | 9 | /// 10 | /// Extensions for StringBuilder 11 | /// 12 | public static class StringBuilderExtensions 13 | { 14 | /// 15 | /// Appends the specified slice to this instance. 16 | /// 17 | /// The builder. 18 | /// The slice. 19 | public static StringBuilder Append(this StringBuilder builder, StringSlice slice) 20 | { 21 | return builder.Append(slice.Text, slice.Start, slice.Length); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Helpers/UnicodeUtility.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using System.Runtime.CompilerServices; 7 | 8 | namespace System.Text; 9 | 10 | // Based on https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/System/Text/UnicodeUtility.cs 11 | internal static class UnicodeUtility 12 | { 13 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 14 | public static bool IsBmpCodePoint(uint value) => value <= 0xFFFFu; 15 | 16 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 17 | public static bool IsValidUnicodeScalar(uint value) 18 | { 19 | return ((value - 0x110000u) ^ 0xD800u) >= 0xFFEF0800u; 20 | } 21 | 22 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 23 | public static void GetUtf16SurrogatesFromSupplementaryPlaneScalar(uint value, out char highSurrogateCodePoint, out char lowSurrogateCodePoint) 24 | { 25 | Debug.Assert(IsValidUnicodeScalar(value) && IsBmpCodePoint(value)); 26 | 27 | highSurrogateCodePoint = (char)((value + ((0xD800u - 0x40u) << 10)) >> 10); 28 | lowSurrogateCodePoint = (char)((value & 0x3FFu) + 0xDC00u); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Markdig/IMarkdownExtension.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Renderers; 6 | 7 | namespace Markdig; 8 | 9 | /// 10 | /// Base interface for an extension. 11 | /// 12 | public interface IMarkdownExtension 13 | { 14 | /// 15 | /// Setups this extension for the specified pipeline. 16 | /// 17 | /// The pipeline. 18 | void Setup(MarkdownPipelineBuilder pipeline); 19 | 20 | /// 21 | /// Setups this extension for the specified renderer. 22 | /// 23 | /// The pipeline used to parse the document. 24 | /// The renderer. 25 | void Setup(MarkdownPipeline pipeline, IMarkdownRenderer renderer); 26 | } -------------------------------------------------------------------------------- /src/Markdig/Markdig.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Markdig 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/Markdig/MarkdownParserContext.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig; 6 | 7 | /// 8 | /// Provides a context that can be used as part of parsing Markdown documents. 9 | /// 10 | public class MarkdownParserContext 11 | { 12 | /// 13 | /// Gets or sets the context property collection. 14 | /// 15 | public Dictionary Properties { get; } 16 | 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | public MarkdownParserContext() 21 | { 22 | Properties = new Dictionary(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Markdig/Parsers/BlockParserList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// A List of . 9 | /// 10 | /// 11 | public class BlockParserList : ParserList 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | /// The parsers. 17 | public BlockParserList(IEnumerable parsers) : base(parsers) 18 | { 19 | } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/BlockState.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// Defines the result of parsing a line for a . 9 | /// 10 | public enum BlockState 11 | { 12 | /// 13 | /// A line is not accepted by this parser. 14 | /// 15 | None, 16 | 17 | /// 18 | /// The parser is skipped. 19 | /// 20 | Skip, 21 | 22 | /// 23 | /// The parser accepts a line and instruct to continue. 24 | /// 25 | Continue, 26 | 27 | /// 28 | /// The parser accepts a line, instruct to continue but discard the line (not stored on the block) 29 | /// 30 | ContinueDiscard, 31 | 32 | /// 33 | /// The parser is ending a block, instruct to stop and keep the line being processed. 34 | /// 35 | Break, 36 | 37 | /// 38 | /// The parser is ending a block, instruct to stop and discard the line being processed. 39 | /// 40 | BreakDiscard 41 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/IAttributesParseable.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax; 7 | 8 | namespace Markdig.Parsers; 9 | 10 | /// 11 | /// A delegates that allows to process attached attributes at time. 12 | /// 13 | /// The processor. 14 | /// The slice to look for attached attributes. 15 | /// The block. 16 | /// true if attributes were found; otherwise false 17 | public delegate bool TryParseAttributesDelegate( 18 | BlockProcessor processor, ref StringSlice slice, IBlock block); 19 | 20 | /// 21 | /// An interface used to tag that supports parsing 22 | /// 23 | public interface IAttributesParseable 24 | { 25 | /// 26 | /// A delegates that allows to process attached attributes 27 | /// 28 | TryParseAttributesDelegate? TryParseAttributes { get; set; } 29 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/IInlineParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Parsers; 8 | 9 | /// 10 | /// Base interface for parsing an . 11 | /// 12 | /// 13 | /// 14 | public interface IInlineParser : IMarkdownParser 15 | { 16 | /// 17 | /// Tries to match the specified slice. 18 | /// 19 | /// The parser processor. 20 | /// The text slice. 21 | /// true if this parser found a match; false otherwise 22 | bool Match(InlineProcessor processor, ref StringSlice slice); 23 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/IMarkdownParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// Base interface for a block or inline parser. 9 | /// 10 | /// The type of processor. 11 | public interface IMarkdownParser 12 | { 13 | /// 14 | /// Gets the opening characters this parser will be triggered if the character is found. 15 | /// 16 | char[]? OpeningCharacters { get; } 17 | 18 | /// 19 | /// Initializes this parser with the specified parser processor. 20 | /// 21 | void Initialize(); 22 | 23 | /// 24 | /// Gets the index of this parser in or . 25 | /// 26 | int Index { get; } 27 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/IPostInlineProcessor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Parsers; 8 | 9 | /// 10 | /// A processor called at the end of processing all inlines. 11 | /// 12 | public interface IPostInlineProcessor 13 | { 14 | /// 15 | /// Processes the delimiters. 16 | /// 17 | /// The parser state. 18 | /// The root inline. 19 | /// The last child. 20 | /// Index of this delimiter processor. 21 | /// 22 | /// true to continue to the next delimiter processor; 23 | /// false to stop the process (in case a processor is performing sub-sequent processor itself) 24 | bool PostProcess(InlineProcessor state, Inline? root, Inline? lastChild, int postInlineProcessorIndex, bool isFinalProcessing); 25 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/InlineParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Parsers; 8 | 9 | /// 10 | /// Base class for parsing an . 11 | /// 12 | /// 13 | public abstract class InlineParser : ParserBase, IInlineParser 14 | { 15 | /// 16 | /// Tries to match the specified slice. 17 | /// 18 | /// The parser processor. 19 | /// The text slice. 20 | /// true if this parser found a match; false otherwise 21 | public abstract bool Match(InlineProcessor processor, ref StringSlice slice); 22 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/InlineParserList.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// A list of . 9 | /// 10 | /// 11 | public class InlineParserList : ParserList 12 | { 13 | public InlineParserList(IEnumerable parsers) : base(parsers) 14 | { 15 | // Prepare the list of post inline processors 16 | var postInlineProcessors = new List(); 17 | foreach (var parser in this) 18 | { 19 | if (parser is IPostInlineProcessor delimProcessor) 20 | { 21 | postInlineProcessors.Add(delimProcessor); 22 | } 23 | } 24 | PostInlineProcessors = postInlineProcessors.ToArray(); 25 | } 26 | 27 | /// 28 | /// Gets the registered post inline processors. 29 | /// 30 | public IPostInlineProcessor[] PostInlineProcessors { get; private set; } 31 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/ListItemParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// A parser base class for a list item. 9 | /// 10 | public abstract class ListItemParser 11 | { 12 | /// 13 | /// Defines the characters that are used for detecting this list item. 14 | /// 15 | public char[]? OpeningCharacters { get; protected set; } 16 | 17 | /// 18 | /// Tries to parse the current input as a list item for this particular instance. 19 | /// 20 | /// The block processor 21 | /// The type of the current bullet type 22 | /// The result of parsing 23 | /// true if parsing was successful; false otherwise 24 | public abstract bool TryParse(BlockProcessor state, char pendingBulletType, out ListInfo result); 25 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/ParserBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// Base class for a or . 9 | /// 10 | /// Type of the parser processor 11 | /// 12 | public abstract class ParserBase : IMarkdownParser 13 | { 14 | /// 15 | /// Gets the opening characters this parser will be triggered if the character is found. 16 | /// 17 | public char[]? OpeningCharacters { get; set; } 18 | 19 | /// 20 | /// Initializes this parser with the specified parser processor. 21 | /// 22 | public virtual void Initialize() 23 | { 24 | } 25 | 26 | /// 27 | /// Gets the index of this parser in or . 28 | /// 29 | public int Index { get; internal set; } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Parsers/UnorderedListItemParser.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Parsers; 6 | 7 | /// 8 | /// The default parser used to parse unordered list item (-, +, *) 9 | /// 10 | /// 11 | public class UnorderedListItemParser : ListItemParser 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public UnorderedListItemParser() 17 | { 18 | OpeningCharacters = ['-', '+', '*']; 19 | } 20 | 21 | public override bool TryParse(BlockProcessor state, char pendingBulletType, out ListInfo result) 22 | { 23 | result = new ListInfo(state.CurrentChar); 24 | state.NextChar(); 25 | return true; 26 | } 27 | } -------------------------------------------------------------------------------- /src/Markdig/Polyfills/Ascii.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if !NET8_0_OR_GREATER 6 | 7 | namespace System.Text; 8 | 9 | internal static class Ascii 10 | { 11 | public static bool IsValid(this string value) 12 | { 13 | return IsValid(value.AsSpan()); 14 | } 15 | 16 | public static bool IsValid(this ReadOnlySpan value) 17 | { 18 | for (int i = 0; i < value.Length; i++) 19 | { 20 | if (value[i] > 127) 21 | { 22 | return false; 23 | } 24 | } 25 | 26 | return true; 27 | } 28 | } 29 | 30 | #endif -------------------------------------------------------------------------------- /src/Markdig/Polyfills/ConcurrentQueue.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if NETFRAMEWORK || NETSTANDARD2_0 6 | namespace System.Collections.Concurrent; 7 | 8 | internal static class ConcurrentQueueExtensions 9 | { 10 | public static void Clear(this ConcurrentQueue queue) 11 | { 12 | while (queue.TryDequeue(out _)) { } 13 | } 14 | } 15 | #endif -------------------------------------------------------------------------------- /src/Markdig/Polyfills/EncodingExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if !NETCOREAPP2_1_OR_GREATER && !NETSTANDARD2_1_OR_GREATER 6 | 7 | using System.Runtime.InteropServices; 8 | 9 | namespace System.Text; 10 | 11 | internal static class EncodingExtensions 12 | { 13 | public static unsafe int GetBytes(this Encoding encoding, ReadOnlySpan chars, Span bytes) 14 | { 15 | fixed (char* charsPtr = &MemoryMarshal.GetReference(chars)) 16 | { 17 | fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes)) 18 | { 19 | return encoding.GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length); 20 | } 21 | } 22 | } 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /src/Markdig/Polyfills/FrozenCollections.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if !NET8_0_OR_GREATER 6 | 7 | namespace System.Collections.Frozen; 8 | 9 | // We're using a polyfill instead of conditionally referencing the package as the package is untested on older TFMs, and 10 | // brings in a reference to System.Runtime.CompilerServices.Unsafe, which conflicts with our polyfills of that type. 11 | 12 | internal sealed class FrozenDictionary : Dictionary 13 | { 14 | public FrozenDictionary(Dictionary dictionary) : base(dictionary) { } 15 | } 16 | 17 | internal static class FrozenDictionaryExtensions 18 | { 19 | public static FrozenDictionary ToFrozenDictionary(this Dictionary dictionary) 20 | { 21 | return new FrozenDictionary(dictionary); 22 | } 23 | } 24 | 25 | internal sealed class FrozenSet : HashSet 26 | { 27 | public FrozenSet(HashSet set, IEqualityComparer comparer) : base(set, comparer) { } 28 | } 29 | 30 | internal static class FrozenSetExtensions 31 | { 32 | public static FrozenSet ToFrozenSet(this HashSet set, IEqualityComparer comparer) 33 | { 34 | return new FrozenSet(set, comparer); 35 | } 36 | } 37 | 38 | #endif -------------------------------------------------------------------------------- /src/Markdig/Polyfills/IndexOfHelpers.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if !NET8_0_OR_GREATER 6 | 7 | namespace System; 8 | 9 | internal static class IndexOfHelpers 10 | { 11 | public static bool ContainsAnyExcept(this ReadOnlySpan span, char value0, char value1, char value2) 12 | { 13 | for (int i = 0; i < span.Length; i++) 14 | { 15 | char c = span[i]; 16 | if (c != value0 && c != value1 && c != value2) 17 | { 18 | return true; 19 | } 20 | } 21 | 22 | return false; 23 | } 24 | 25 | #if !NETSTANDARD2_1_OR_GREATER 26 | public static int IndexOfAny(this ReadOnlySpan span, string values) 27 | { 28 | for (int i = 0; i < span.Length; i++) 29 | { 30 | char c = span[i]; 31 | 32 | foreach (char v in values) 33 | { 34 | if (c == v) 35 | { 36 | return i; 37 | } 38 | } 39 | } 40 | 41 | return -1; 42 | } 43 | #endif 44 | 45 | #if !NET6_0_OR_GREATER 46 | public static bool Contains(this ReadOnlySpan span, T value) where T : IEquatable 47 | { 48 | return span.IndexOf(value) >= 0; 49 | } 50 | #endif 51 | } 52 | 53 | #endif -------------------------------------------------------------------------------- /src/Markdig/Polyfills/NullableAttributes.cs: -------------------------------------------------------------------------------- 1 | // Based on code at located at https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs 2 | 3 | // Licensed to the .NET Foundation under one or more agreements. 4 | // The .NET Foundation licenses this file to you under the MIT license. 5 | 6 | namespace System.Diagnostics.CodeAnalysis; 7 | 8 | #if !NETSTANDARD2_1_OR_GREATER && !NETCOREAPP3_1_OR_GREATER 9 | internal sealed class DoesNotReturnAttribute : Attribute { } 10 | 11 | [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] 12 | internal sealed class NotNullWhenAttribute : Attribute 13 | { 14 | public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; 15 | 16 | public bool ReturnValue { get; } 17 | } 18 | 19 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)] 20 | internal sealed class AllowNullAttribute : Attribute { } 21 | 22 | [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] 23 | internal sealed class MaybeNullAttribute : Attribute { } 24 | #endif 25 | 26 | #if !NET5_0_OR_GREATER 27 | internal sealed class MemberNotNullAttribute : Attribute 28 | { 29 | public MemberNotNullAttribute(string member) => Members = [member]; 30 | 31 | public MemberNotNullAttribute(params string[] members) => Members = members; 32 | 33 | public string[] Members { get; } 34 | } 35 | #endif 36 | -------------------------------------------------------------------------------- /src/Markdig/Polyfills/SpanExtensions.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if NET462 || NETSTANDARD2_0 6 | 7 | using System.Diagnostics; 8 | 9 | namespace System; 10 | 11 | internal static class SpanExtensions 12 | { 13 | public static bool StartsWith(this ReadOnlySpan span, string prefix, StringComparison comparisonType) 14 | { 15 | Debug.Assert(comparisonType is StringComparison.Ordinal or StringComparison.OrdinalIgnoreCase); 16 | 17 | return 18 | span.Length >= prefix.Length && 19 | span.Slice(0, prefix.Length).Equals(prefix.AsSpan(), comparisonType); 20 | } 21 | } 22 | 23 | #endif -------------------------------------------------------------------------------- /src/Markdig/Polyfills/Unsafe.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if NETSTANDARD2_1 6 | 7 | using System.Diagnostics.CodeAnalysis; 8 | 9 | namespace System.Runtime.CompilerServices; 10 | 11 | internal static class Unsafe 12 | { 13 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 14 | [return: NotNullIfNotNull(nameof(o))] 15 | public static T? As(object? o) where T : class 16 | { 17 | return (T?)o; 18 | } 19 | } 20 | #endif -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/HeadingRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// An HTML renderer for a . 11 | /// 12 | /// 13 | public class HeadingRenderer : HtmlObjectRenderer 14 | { 15 | private static readonly string[] HeadingTexts = [ 16 | "h1", 17 | "h2", 18 | "h3", 19 | "h4", 20 | "h5", 21 | "h6", 22 | ]; 23 | 24 | protected override void Write(HtmlRenderer renderer, HeadingBlock obj) 25 | { 26 | int index = obj.Level - 1; 27 | string[] headings = HeadingTexts; 28 | string headingText = ((uint)index < (uint)headings.Length) 29 | ? headings[index] 30 | : $"h{obj.Level}"; 31 | 32 | if (renderer.EnableHtmlForBlock) 33 | { 34 | renderer.Write('<'); 35 | renderer.WriteRaw(headingText); 36 | renderer.WriteAttributes(obj); 37 | renderer.WriteRaw('>'); 38 | } 39 | 40 | renderer.WriteLeafInline(obj); 41 | 42 | if (renderer.EnableHtmlForBlock) 43 | { 44 | renderer.Write("'); 47 | } 48 | 49 | renderer.EnsureLine(); 50 | } 51 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/HtmlBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class HtmlBlockRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, HtmlBlock obj) 16 | { 17 | renderer.WriteLeafRawLines(obj, true, false); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/HtmlObjectRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// A base class for HTML rendering and Markdown objects. 11 | /// 12 | /// The type of the object. 13 | /// 14 | public abstract class HtmlObjectRenderer : MarkdownObjectRenderer where TObject : MarkdownObject 15 | { 16 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/CodeInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class CodeInlineRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, CodeInline obj) 16 | { 17 | if (renderer.EnableHtmlForInline) 18 | { 19 | renderer.Write("'); 22 | } 23 | if (renderer.EnableHtmlEscape) 24 | { 25 | renderer.WriteEscape(obj.ContentSpan); 26 | } 27 | else 28 | { 29 | renderer.Write(obj.ContentSpan); 30 | } 31 | if (renderer.EnableHtmlForInline) 32 | { 33 | renderer.WriteRaw(""); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/DelimiterInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class DelimiterInlineRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, DelimiterInline obj) 16 | { 17 | renderer.WriteEscape(obj.ToLiteral()); 18 | renderer.WriteChildren(obj); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/HtmlEntityInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class HtmlEntityInlineRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, HtmlEntityInline obj) 16 | { 17 | if (renderer.EnableHtmlEscape) 18 | { 19 | renderer.WriteEscape(obj.Transcoded); 20 | } 21 | else 22 | { 23 | renderer.Write(obj.Transcoded); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/HtmlInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class HtmlInlineRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, HtmlInline obj) 16 | { 17 | if (renderer.EnableHtmlForInline) 18 | { 19 | renderer.Write(obj.Tag); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/LineBreakInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class LineBreakInlineRenderer : HtmlObjectRenderer 14 | { 15 | /// 16 | /// Gets or sets a value indicating whether to render this softline break as a HTML hardline break tag (<br />) 17 | /// 18 | public bool RenderAsHardlineBreak { get; set; } 19 | 20 | protected override void Write(HtmlRenderer renderer, LineBreakInline obj) 21 | { 22 | if (renderer.IsLastInContainer) return; 23 | 24 | if (renderer.EnableHtmlForInline) 25 | { 26 | if (obj.IsHard || RenderAsHardlineBreak) 27 | { 28 | renderer.WriteLine("
"); 29 | } 30 | } 31 | 32 | renderer.EnsureLine(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/Inlines/LiteralInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Html.Inlines; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class LiteralInlineRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, LiteralInline obj) 16 | { 17 | if (renderer.EnableHtmlEscape) 18 | { 19 | renderer.WriteEscape(ref obj.Content); 20 | } 21 | else 22 | { 23 | renderer.Write(ref obj.Content); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/ParagraphRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class ParagraphRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, ParagraphBlock obj) 16 | { 17 | if (!renderer.ImplicitParagraph && renderer.EnableHtmlForBlock) 18 | { 19 | if (!renderer.IsFirstInContainer) 20 | { 21 | renderer.EnsureLine(); 22 | } 23 | 24 | renderer.Write("'); 27 | } 28 | renderer.WriteLeafInline(obj); 29 | if (!renderer.ImplicitParagraph) 30 | { 31 | if (renderer.EnableHtmlForBlock) 32 | { 33 | renderer.WriteLine("

"); 34 | } 35 | 36 | renderer.EnsureLine(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/QuoteBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class QuoteBlockRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, QuoteBlock obj) 16 | { 17 | renderer.EnsureLine(); 18 | if (renderer.EnableHtmlForBlock) 19 | { 20 | renderer.Write("'); 23 | } 24 | var savedImplicitParagraph = renderer.ImplicitParagraph; 25 | renderer.ImplicitParagraph = false; 26 | renderer.WriteChildren(obj); 27 | renderer.ImplicitParagraph = savedImplicitParagraph; 28 | if (renderer.EnableHtmlForBlock) 29 | { 30 | renderer.WriteLine("
"); 31 | } 32 | renderer.EnsureLine(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Html/ThematicBreakRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Html; 8 | 9 | /// 10 | /// A HTML renderer for a . 11 | /// 12 | /// 13 | public class ThematicBreakRenderer : HtmlObjectRenderer 14 | { 15 | protected override void Write(HtmlRenderer renderer, ThematicBreakBlock obj) 16 | { 17 | if (renderer.EnableHtmlForBlock) 18 | { 19 | renderer.Write(""); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/IMarkdownObjectRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers; 8 | 9 | /// 10 | /// Base interface for the renderer of a . 11 | /// 12 | public interface IMarkdownObjectRenderer 13 | { 14 | /// 15 | /// Accepts the specified . 16 | /// 17 | /// The renderer. 18 | /// The of the Markdown object. 19 | /// true If this renderer is accepting to render the specified Markdown object 20 | bool Accept(RendererBase renderer, Type objectType); 21 | 22 | /// 23 | /// Writes the specified to the . 24 | /// 25 | /// The renderer. 26 | /// The object to render. 27 | void Write(RendererBase renderer, MarkdownObject objectToRender); 28 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/IMarkdownRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Renderers; 9 | 10 | /// 11 | /// Base interface for a renderer for a Markdown . 12 | /// 13 | public interface IMarkdownRenderer 14 | { 15 | /// 16 | /// Occurs when before writing an object. 17 | /// 18 | event Action ObjectWriteBefore; 19 | 20 | /// 21 | /// Occurs when after writing an object. 22 | /// 23 | event Action ObjectWriteAfter; 24 | 25 | /// 26 | /// Gets the object renderers that will render and elements. 27 | /// 28 | ObjectRendererCollection ObjectRenderers { get; } 29 | 30 | /// 31 | /// Renders the specified markdown object. 32 | /// 33 | /// The markdown object. 34 | /// The result of the rendering. 35 | object Render(MarkdownObject markdownObject); 36 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/HeadingRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | /// 10 | /// An Normalize renderer for a . 11 | /// 12 | /// 13 | public class HeadingRenderer : NormalizeObjectRenderer 14 | { 15 | private static readonly string[] HeadingTexts = [ 16 | "#", 17 | "##", 18 | "###", 19 | "####", 20 | "#####", 21 | "######", 22 | ]; 23 | 24 | protected override void Write(NormalizeRenderer renderer, HeadingBlock obj) 25 | { 26 | if (obj.Level is > 0 and <= 6) 27 | { 28 | renderer.Write(HeadingTexts[obj.Level - 1]); 29 | } 30 | else 31 | { 32 | renderer.Write('#', obj.Level); 33 | } 34 | 35 | renderer.Write(' '); 36 | renderer.WriteLeafInline(obj); 37 | 38 | renderer.FinishBlock(renderer.Options.EmptyLineAfterHeading); 39 | } 40 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/HtmlBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | public class HtmlBlockRenderer : NormalizeObjectRenderer 10 | { 11 | protected override void Write(NormalizeRenderer renderer, HtmlBlock obj) 12 | { 13 | renderer.WriteLeafRawLines(obj, true, false); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/AutolinkInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for an . 11 | /// 12 | /// 13 | public class AutolinkInlineRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, AutolinkInline obj) 16 | { 17 | renderer.Write('<').Write(obj.Url).Write('>'); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/DelimiterInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class DelimiterInlineRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, DelimiterInline obj) 16 | { 17 | renderer.Write(obj.ToLiteral()); 18 | renderer.WriteChildren(obj); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/EmphasisInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for an . 11 | /// 12 | /// 13 | public class EmphasisInlineRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, EmphasisInline obj) 16 | { 17 | renderer.Write(obj.DelimiterChar, obj.DelimiterCount); 18 | renderer.WriteChildren(obj); 19 | renderer.Write(obj.DelimiterChar, obj.DelimiterCount); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/LineBreakInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class LineBreakInlineRenderer : NormalizeObjectRenderer 14 | { 15 | /// 16 | /// Gets or sets a value indicating whether to render this softline break as a Normalize hardline break tag (<br />) 17 | /// 18 | public bool RenderAsHardlineBreak { get; set; } 19 | 20 | protected override void Write(NormalizeRenderer renderer, LineBreakInline obj) 21 | { 22 | if (obj.IsHard) 23 | { 24 | renderer.Write(obj.IsBackslash ? "\\" : " "); 25 | } 26 | renderer.WriteLine(); 27 | } 28 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/LiteralInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Renderers.Normalize.Inlines; 9 | 10 | /// 11 | /// A Normalize renderer for a . 12 | /// 13 | /// 14 | public class LiteralInlineRenderer : NormalizeObjectRenderer 15 | { 16 | protected override void Write(NormalizeRenderer renderer, LiteralInline obj) 17 | { 18 | if (obj.IsFirstCharacterEscaped && obj.Content.Length > 0 && obj.Content[obj.Content.Start].IsAsciiPunctuation()) 19 | { 20 | renderer.Write('\\'); 21 | } 22 | renderer.Write(ref obj.Content); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/NormalizeHtmlEntityInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | public class NormalizeHtmlEntityInlineRenderer : NormalizeObjectRenderer 13 | { 14 | protected override void Write(NormalizeRenderer renderer, HtmlEntityInline obj) 15 | { 16 | renderer.Write(obj.Original); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/Inlines/NormalizeHtmlInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Normalize.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | public class NormalizeHtmlInlineRenderer : NormalizeObjectRenderer 13 | { 14 | protected override void Write(NormalizeRenderer renderer, HtmlInline obj) 15 | { 16 | renderer.Write(obj.Tag); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/LinkReferenceDefinitionGroupRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | public class LinkReferenceDefinitionGroupRenderer : NormalizeObjectRenderer 10 | { 11 | protected override void Write(NormalizeRenderer renderer, LinkReferenceDefinitionGroup obj) 12 | { 13 | renderer.EnsureLine(); 14 | renderer.WriteChildren(obj); 15 | renderer.FinishBlock(false); 16 | } 17 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/LinkReferenceDefinitionRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | public class LinkReferenceDefinitionRenderer : NormalizeObjectRenderer 10 | { 11 | protected override void Write(NormalizeRenderer renderer, LinkReferenceDefinition linkDef) 12 | { 13 | renderer.EnsureLine(); 14 | renderer.Write('['); 15 | renderer.Write(linkDef.Label); 16 | renderer.Write("]: "); 17 | 18 | renderer.Write(linkDef.Url); 19 | 20 | if (linkDef.Title != null) 21 | { 22 | renderer.Write(" \""); 23 | renderer.Write(linkDef.Title.Replace("\"", "\\\"")); 24 | renderer.Write('"'); 25 | } 26 | renderer.FinishBlock(false); 27 | } 28 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/NormalizeObjectRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | /// 10 | /// A base class for Normalize rendering and Markdown objects. 11 | /// 12 | /// The type of the object. 13 | /// 14 | public abstract class NormalizeObjectRenderer : MarkdownObjectRenderer where TObject : MarkdownObject 15 | { 16 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/ParagraphRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class ParagraphRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, ParagraphBlock obj) 16 | { 17 | renderer.WriteLeafInline(obj); 18 | renderer.FinishBlock(!renderer.CompactParagraph); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/QuoteBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class QuoteBlockRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, QuoteBlock obj) 16 | { 17 | var quoteIndent = renderer.Options.SpaceAfterQuoteBlock ? obj.QuoteChar + " " : obj.QuoteChar.ToString(); 18 | renderer.PushIndent(quoteIndent); 19 | renderer.WriteChildren(obj); 20 | renderer.PopIndent(); 21 | 22 | renderer.FinishBlock(true); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Normalize/ThematicBreakRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Normalize; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class ThematicBreakRenderer : NormalizeObjectRenderer 14 | { 15 | protected override void Write(NormalizeRenderer renderer, ThematicBreakBlock obj) 16 | { 17 | renderer.WriteLine(new string(obj.ThematicChar, obj.ThematicCharCount)); 18 | 19 | renderer.FinishBlock(renderer.Options.EmptyLineAfterThematicBreak); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/ObjectRendererCollection.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Renderers; 8 | 9 | /// 10 | /// A collection of . 11 | /// 12 | /// 13 | public class ObjectRendererCollection : OrderedList 14 | { 15 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/EmptyBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Roundtrip; 8 | 9 | public class EmptyBlockRenderer : RoundtripObjectRenderer 10 | { 11 | protected override void Write(RoundtripRenderer renderer, EmptyBlock noBlocksFoundBlock) 12 | { 13 | renderer.RenderLinesAfter(noBlocksFoundBlock); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/HtmlBlockRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Roundtrip; 8 | 9 | public class HtmlBlockRenderer : RoundtripObjectRenderer 10 | { 11 | protected override void Write(RoundtripRenderer renderer, HtmlBlock obj) 12 | { 13 | renderer.RenderLinesBefore(obj); 14 | //renderer.Write(obj.BeforeWhitespace); // Lines content is written, including whitespace 15 | renderer.WriteLeafRawLines(obj); 16 | renderer.RenderLinesAfter(obj); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/AutolinkInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for an . 11 | /// 12 | /// 13 | public class AutolinkInlineRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, AutolinkInline obj) 16 | { 17 | renderer.Write('<').Write(obj.Url).Write('>'); 18 | } 19 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/CodeInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class CodeInlineRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, CodeInline obj) 16 | { 17 | renderer.Write(obj.Delimiter, obj.DelimiterCount); 18 | if (!obj.ContentSpan.IsEmpty) 19 | { 20 | renderer.Write(obj.ContentWithTrivia); 21 | } 22 | renderer.Write(obj.Delimiter, obj.DelimiterCount); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/DelimiterInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class DelimiterInlineRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, DelimiterInline obj) 16 | { 17 | renderer.Write(obj.ToLiteral()); 18 | renderer.WriteChildren(obj); 19 | } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/EmphasisInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for an . 11 | /// 12 | /// 13 | public class EmphasisInlineRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, EmphasisInline obj) 16 | { 17 | renderer.Write(obj.DelimiterChar, obj.DelimiterCount); 18 | renderer.WriteChildren(obj); 19 | renderer.Write(obj.DelimiterChar, obj.DelimiterCount); 20 | } 21 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/LineBreakInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | /// 13 | public class LineBreakInlineRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, LineBreakInline obj) 16 | { 17 | if (obj.IsHard && obj.IsBackslash) 18 | { 19 | renderer.Write("\\"); 20 | } 21 | renderer.WriteLine(obj.NewLine); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/LiteralInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Syntax.Inlines; 7 | 8 | namespace Markdig.Renderers.Roundtrip.Inlines; 9 | 10 | /// 11 | /// A Normalize renderer for a . 12 | /// 13 | /// 14 | public class LiteralInlineRenderer : RoundtripObjectRenderer 15 | { 16 | protected override void Write(RoundtripRenderer renderer, LiteralInline obj) 17 | { 18 | if (obj.IsFirstCharacterEscaped && obj.Content.Length > 0 && obj.Content[obj.Content.Start].IsAsciiPunctuation()) 19 | { 20 | renderer.Write('\\'); 21 | } 22 | renderer.Write(ref obj.Content); 23 | } 24 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/RoundtripHtmlEntityInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | public class RoundtripHtmlEntityInlineRenderer : RoundtripObjectRenderer 13 | { 14 | protected override void Write(RoundtripRenderer renderer, HtmlEntityInline obj) 15 | { 16 | renderer.Write(obj.Original); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/Inlines/RoundtripHtmlInlineRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax.Inlines; 6 | 7 | namespace Markdig.Renderers.Roundtrip.Inlines; 8 | 9 | /// 10 | /// A Normalize renderer for a . 11 | /// 12 | public class RoundtripHtmlInlineRenderer : RoundtripObjectRenderer 13 | { 14 | protected override void Write(RoundtripRenderer renderer, HtmlInline obj) 15 | { 16 | renderer.Write(obj.Tag); 17 | } 18 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/LinkReferenceDefinitionGroupRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Roundtrip; 8 | 9 | public class LinkReferenceDefinitionGroupRenderer : RoundtripObjectRenderer 10 | { 11 | protected override void Write(RoundtripRenderer renderer, LinkReferenceDefinitionGroup obj) 12 | { 13 | renderer.WriteChildren(obj); 14 | } 15 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/ParagraphRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | using System.Diagnostics; 7 | 8 | namespace Markdig.Renderers.Roundtrip; 9 | 10 | /// 11 | /// A Roundtrip renderer for a . 12 | /// 13 | /// 14 | [DebuggerDisplay("renderer.Writer.ToString()")] 15 | public class ParagraphRenderer : RoundtripObjectRenderer 16 | { 17 | protected override void Write(RoundtripRenderer renderer, ParagraphBlock paragraph) 18 | { 19 | renderer.RenderLinesBefore(paragraph); 20 | renderer.Write(paragraph.TriviaBefore); 21 | renderer.WriteLeafInline(paragraph); 22 | //renderer.Write(paragraph.Newline); // paragraph typically has LineBreakInlines as closing inline nodes 23 | renderer.RenderLinesAfter(paragraph); 24 | } 25 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/RoundtripObjectRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Roundtrip; 8 | 9 | /// 10 | /// A base class for Normalize rendering and Markdown objects. 11 | /// 12 | /// The type of the object. 13 | /// 14 | public abstract class RoundtripObjectRenderer : MarkdownObjectRenderer where TObject : MarkdownObject 15 | { 16 | } -------------------------------------------------------------------------------- /src/Markdig/Renderers/Roundtrip/ThematicBreakRenderer.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Syntax; 6 | 7 | namespace Markdig.Renderers.Roundtrip; 8 | 9 | /// 10 | /// A Roundtrip renderer for a . 11 | /// 12 | /// 13 | public class ThematicBreakRenderer : RoundtripObjectRenderer 14 | { 15 | protected override void Write(RoundtripRenderer renderer, ThematicBreakBlock obj) 16 | { 17 | renderer.RenderLinesBefore(obj); 18 | 19 | renderer.Write(obj.Content); 20 | renderer.WriteLine(obj.NewLine); 21 | renderer.RenderLinesAfter(obj); 22 | } 23 | } -------------------------------------------------------------------------------- /src/Markdig/SkipLocalsInit.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | #if NET5_0_OR_GREATER 6 | [module: System.Runtime.CompilerServices.SkipLocalsInit] 7 | #endif 8 | -------------------------------------------------------------------------------- /src/Markdig/Syntax/BlankLineBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax; 6 | 7 | /// 8 | /// A blank line, used internally by some parsers to store blank lines in a container. They are removed before the end of the document. 9 | /// 10 | /// 11 | public sealed class BlankLineBlock : Block 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public BlankLineBlock() : base(null) 17 | { 18 | // A blankline is never opened 19 | IsOpen = false; 20 | } 21 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/CodeBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Parsers; 7 | 8 | namespace Markdig.Syntax; 9 | 10 | /// 11 | /// Represents an indented code block. 12 | /// 13 | /// 14 | /// Related to CommonMark spec: 4.4 Indented code blocks 15 | /// 16 | public class CodeBlock : LeafBlock 17 | { 18 | public class CodeBlockLine 19 | { 20 | public StringSlice TriviaBefore { get; set; } 21 | } 22 | 23 | private List? _codeBlockLines; 24 | public List CodeBlockLines => _codeBlockLines ??= []; 25 | 26 | /// 27 | /// Initializes a new instance of the class. 28 | /// 29 | /// The parser. 30 | public CodeBlock(BlockParser parser) : base(parser) 31 | { 32 | } 33 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/HtmlBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | 7 | namespace Markdig.Syntax; 8 | 9 | /// 10 | /// Represents a group of lines that is treated as raw HTML (and will not be escaped in HTML output). 11 | /// 12 | /// 13 | public class HtmlBlock : LeafBlock 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The parser. 19 | public HtmlBlock(BlockParser? parser) : base(parser) 20 | { 21 | } 22 | 23 | /// 24 | /// Gets or sets the type of block. 25 | /// 26 | public HtmlBlockType Type { get; set; } 27 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/HtmlBlockType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax; 6 | 7 | /// 8 | /// Defines the type of 9 | /// 10 | public enum HtmlBlockType 11 | { 12 | /// 13 | /// A SGML document type starting by <!LETTER. 14 | /// 15 | DocumentType, 16 | 17 | /// 18 | /// A raw CDATA sequence. 19 | /// 20 | CData, 21 | 22 | /// 23 | /// A HTML comment. 24 | /// 25 | Comment, 26 | 27 | /// 28 | /// A SGM processing instruction tag <? 29 | /// 30 | ProcessingInstruction, 31 | 32 | /// 33 | /// A script pre or style tag. 34 | /// 35 | ScriptPreOrStyle, 36 | 37 | /// 38 | /// An HTML interrupting block 39 | /// 40 | InterruptingBlock, 41 | 42 | /// 43 | /// An HTML non-interrupting block 44 | /// 45 | NonInterruptingBlock 46 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/AutolinkInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | 7 | namespace Markdig.Syntax.Inlines; 8 | 9 | /// 10 | /// An autolink (Section 6.7 CommonMark specs) 11 | /// 12 | /// 13 | [DebuggerDisplay("<{Url}>")] 14 | public sealed class AutolinkInline : LeafInline 15 | { 16 | public AutolinkInline(string url) 17 | { 18 | Url = url; 19 | } 20 | 21 | /// 22 | /// Gets or sets a value indicating whether this instance is an email link. 23 | /// 24 | public bool IsEmail { get; set; } 25 | 26 | /// 27 | /// Gets or sets the URL of this link. 28 | /// 29 | public string Url { get; set; } 30 | 31 | public override string ToString() 32 | { 33 | return Url; 34 | } 35 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/DelimiterType.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax.Inlines; 6 | 7 | /// 8 | /// Gets the type of a . 9 | /// 10 | [Flags] 11 | public enum DelimiterType : byte 12 | { 13 | /// 14 | /// An undefined open or close delimiter. 15 | /// 16 | Undefined, 17 | 18 | /// 19 | /// An open delimiter. 20 | /// 21 | Open, 22 | 23 | /// 24 | /// A close delimiter. 25 | /// 26 | Close, 27 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/EmphasisInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | 7 | namespace Markdig.Syntax.Inlines; 8 | 9 | /// 10 | /// An emphasis and strong emphasis (Section 6.4 CommonMark specs). 11 | /// 12 | /// 13 | [DebuggerDisplay("{DelimiterChar} Count: {DelimiterCount}")] 14 | public class EmphasisInline : ContainerInline 15 | { 16 | /// 17 | /// Gets or sets the delimiter character of this emphasis. 18 | /// 19 | public char DelimiterChar { get; set; } 20 | 21 | /// 22 | /// Gets or sets a value indicating whether this is strong. 23 | /// Marked obsolete as EmphasisInline can now be represented by more than two delimiter characters 24 | /// 25 | [Obsolete("Use `DelimiterCount == 2` instead", error: false)] 26 | public bool IsDouble 27 | { 28 | get => DelimiterCount == 2; 29 | set => DelimiterCount = value ? 2 : 1; 30 | } 31 | 32 | /// 33 | /// Gets or sets the number of delimiter characters for this emphasis. 34 | /// 35 | public int DelimiterCount { get; set; } 36 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/HtmlEntityInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | using Markdig.Helpers; 7 | 8 | namespace Markdig.Syntax.Inlines; 9 | 10 | /// 11 | /// An entity HTML. 12 | /// 13 | /// 14 | [DebuggerDisplay("{Original} -> {Transcoded}")] 15 | public class HtmlEntityInline : LeafInline 16 | { 17 | /// 18 | /// Gets or sets the original HTML entity name 19 | /// 20 | public StringSlice Original { get; set; } 21 | 22 | /// 23 | /// Gets or sets the transcoded literal that will be used for output 24 | /// 25 | public StringSlice Transcoded { get; set; } 26 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/HtmlInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using System.Diagnostics; 6 | 7 | namespace Markdig.Syntax.Inlines; 8 | 9 | /// 10 | /// A Raw HTML (Section 6.8 CommonMark specs). 11 | /// 12 | /// 13 | [DebuggerDisplay("{Tag}")] 14 | public class HtmlInline : LeafInline 15 | { 16 | public HtmlInline(string tag) 17 | { 18 | Tag = tag; 19 | } 20 | 21 | /// 22 | /// Gets or sets the full declaration of this tag. 23 | /// 24 | public string Tag { get; set; } 25 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/IInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax.Inlines; 6 | 7 | /// 8 | /// Base interface for all syntax tree inlines. 9 | /// 10 | /// 11 | public interface IInline : IMarkdownObject 12 | { 13 | /// 14 | /// Gets the parent container of this inline. 15 | /// 16 | ContainerInline? Parent { get; } 17 | 18 | /// 19 | /// Gets the previous inline. 20 | /// 21 | Inline? PreviousSibling { get; } 22 | 23 | /// 24 | /// Gets the next sibling inline. 25 | /// 26 | Inline? NextSibling { get; } 27 | 28 | /// 29 | /// Gets or sets a value indicating whether this instance is closed. 30 | /// 31 | bool IsClosed { get; set; } 32 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/LeafInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax.Inlines; 6 | 7 | /// 8 | /// A base class for a leaf inline. 9 | /// 10 | /// 11 | public abstract class LeafInline : Inline 12 | { 13 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/Inlines/LineBreakInline.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | 7 | namespace Markdig.Syntax.Inlines; 8 | 9 | /// 10 | /// A base class for a line break. 11 | /// 12 | /// 13 | public class LineBreakInline : LeafInline 14 | { 15 | public bool IsHard { get; set; } 16 | 17 | public bool IsBackslash { get; set; } 18 | 19 | public NewLine NewLine { get; set; } 20 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/MarkdownDocument.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | namespace Markdig.Syntax; 6 | 7 | /// 8 | /// The root Markdown document. 9 | /// 10 | /// 11 | public class MarkdownDocument : ContainerBlock 12 | { 13 | /// 14 | /// Initializes a new instance of the class. 15 | /// 16 | public MarkdownDocument() : base(null) 17 | { 18 | } 19 | 20 | /// 21 | /// Gets the number of lines in this 22 | /// 23 | public int LineCount; 24 | 25 | /// 26 | /// Gets a list of zero-based indexes of line beginnings in the source span 27 | /// Available if is used, otherwise null 28 | /// 29 | public List? LineStartIndexes { get; set; } 30 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/NoBlocksFoundBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | 7 | namespace Markdig.Syntax; 8 | 9 | /// 10 | /// Block representing a document with characters but no blocks. This can 11 | /// happen when an input document consists solely of trivia. 12 | /// 13 | public sealed class EmptyBlock : LeafBlock 14 | { 15 | public EmptyBlock (BlockParser? parser) : base(parser) 16 | { 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Markdig/Syntax/ParagraphBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Parsers; 6 | 7 | namespace Markdig.Syntax; 8 | 9 | /// 10 | /// Represents a paragraph. 11 | /// 12 | /// 13 | /// Related to CommonMark spec: 4.8 Paragraphs 14 | /// 15 | public class ParagraphBlock : LeafBlock 16 | { 17 | /// 18 | /// Initializes a new instance of the class. 19 | /// 20 | public ParagraphBlock() : this(null) 21 | { 22 | } 23 | 24 | /// 25 | /// Initializes a new instance of the class. 26 | /// 27 | /// The parser used to create this block. 28 | public ParagraphBlock(BlockParser? parser) : base(parser) 29 | { 30 | // Inlines are processed for a paragraph 31 | ProcessInlines = true; 32 | IsParagraphBlock = true; 33 | } 34 | 35 | public int LastLine => Line + Lines.Count - 1; 36 | } -------------------------------------------------------------------------------- /src/Markdig/Syntax/ThematicBreakBlock.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) Alexandre Mutel. All rights reserved. 2 | // This file is licensed under the BSD-Clause 2 license. 3 | // See the license.txt file in the project root for more information. 4 | 5 | using Markdig.Helpers; 6 | using Markdig.Parsers; 7 | 8 | namespace Markdig.Syntax; 9 | 10 | /// 11 | /// Represents a thematic break (Section 4.1 CommonMark specs). 12 | /// 13 | public class ThematicBreakBlock : LeafBlock 14 | { 15 | /// 16 | /// Initializes a new instance of the class. 17 | /// 18 | /// The parser used to create this block. 19 | public ThematicBreakBlock(BlockParser parser) : base(parser) 20 | { 21 | } 22 | 23 | public char ThematicChar { get; set; } 24 | 25 | public int ThematicCharCount { get; set; } 26 | 27 | public StringSlice Content; 28 | } -------------------------------------------------------------------------------- /src/Markdig/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | uid: Markdig 3 | --- 4 | 5 | # Summary 6 | 7 | Contains the top level classes for using Markdig. The entry user class is . -------------------------------------------------------------------------------- /src/SpecFileGen/SpecFileGen.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0;net8.0;net9.0 6 | enable 7 | false 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/UnicodeNormDApp/UnicodeNormDApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net8.0 5 | false 6 | enable 7 | 8 | -------------------------------------------------------------------------------- /src/dotnet-releaser.toml: -------------------------------------------------------------------------------- 1 | [msbuild] 2 | project = ["markdig.sln", "./Markdig.Signed/Markdig.Signed.csproj"] 3 | build_debug = true 4 | [github] 5 | user = "xoofx" 6 | repo = "markdig" 7 | [test] 8 | run_tests_for_debug = true 9 | [coverage] 10 | exclude = "[SpecFileGen*]*" -------------------------------------------------------------------------------- /src/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "9.0.100", 4 | "rollForward": "latestMinor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /src/mdtoc/mdtoc.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | Exe 4 | net8.0 5 | false 6 | enable 7 | enable 8 | 9 | 10 | 11 | 12 | --------------------------------------------------------------------------------