feat: implemented wiki links for both HTML and Gemtext
This commit is contained in:
parent
45f26437ff
commit
cd9c8989dc
47 changed files with 670 additions and 106 deletions
|
@ -9,6 +9,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Markdown.Gemtext",
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Markdown.Gemtext.Tests", "tests\MfGames.Markdown.Gemtext.Tests\MfGames.Markdown.Gemtext.Tests.csproj", "{D2703B25-9AF7-49FF-93A4-CB124560F2A9}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Markdown.Gemtext.Tests", "tests\MfGames.Markdown.Gemtext.Tests\MfGames.Markdown.Gemtext.Tests.csproj", "{D2703B25-9AF7-49FF-93A4-CB124560F2A9}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{B4837F83-8560-4AC9-B1E3-6B8C0545A65B}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Markdown", "src\MfGames.Markdown\MfGames.Markdown.csproj", "{482E332F-9E72-4F02-B528-9CF04AE05E82}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MfGames.Markdown.Tests", "tests\MfGames.Markdown.Tests\MfGames.Markdown.Tests.csproj", "{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -46,9 +52,35 @@ Global
|
||||||
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x64.Build.0 = Release|Any CPU
|
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x86.ActiveCfg = Release|Any CPU
|
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x86.Build.0 = Release|Any CPU
|
{D2703B25-9AF7-49FF-93A4-CB124560F2A9}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{2A1DE43D-544D-4CE0-ACC8-D15497BBCECA} = {954BA984-D50E-4D1C-880F-EAE678EF6945}
|
{2A1DE43D-544D-4CE0-ACC8-D15497BBCECA} = {954BA984-D50E-4D1C-880F-EAE678EF6945}
|
||||||
{D2703B25-9AF7-49FF-93A4-CB124560F2A9} = {954BA984-D50E-4D1C-880F-EAE678EF6945}
|
{D2703B25-9AF7-49FF-93A4-CB124560F2A9} = {B4837F83-8560-4AC9-B1E3-6B8C0545A65B}
|
||||||
|
{482E332F-9E72-4F02-B528-9CF04AE05E82} = {954BA984-D50E-4D1C-880F-EAE678EF6945}
|
||||||
|
{3E2AD98D-D1A1-48DF-B94F-A470982DAC9B} = {B4837F83-8560-4AC9-B1E3-6B8C0545A65B}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
34
README.md
34
README.md
|
@ -1,3 +1,33 @@
|
||||||
# MfGames.Markdown.Gemtext CIL
|
# MfGames.Markdown CIL
|
||||||
|
|
||||||
An extension for [Markdig](https://github.com/xoofx/markdig) that converts Markdown into Gemtext.
|
This is a set of libraries for working with Markdown in C#. Most of the code are extensions in [MarkDig](https://github.com/xoofx/markdig), an extensible library for converting Markdown.
|
||||||
|
|
||||||
|
The library includes the following:
|
||||||
|
|
||||||
|
- An extension for converting wiki links, such as `[[MfGames]]` into a link based on the title. This is for both HTML and Gemtext.
|
||||||
|
- A output library for using MarkDig to generate Gemtext for Gemini pods.
|
||||||
|
|
||||||
|
The documentation is rather light at the moment, but the tests are set up to show these can be used.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
These library are not on nuget.org (for various reasons). To use them, set up your NuGet.config to pull them from their repository.
|
||||||
|
|
||||||
|
```
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<clear />
|
||||||
|
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||||
|
<add key="mfgames.com" value="https://src.mfgames.com/api/packages/mfgames-cil/nuget/index.json" protocolVersion="3" />
|
||||||
|
</packageSources>
|
||||||
|
<packageSourceMapping>
|
||||||
|
<packageSource key="nuget.org">
|
||||||
|
<package pattern="*" />
|
||||||
|
</packageSource>
|
||||||
|
<packageSource key="mfgames.com">
|
||||||
|
<package pattern="MfGames.*" />
|
||||||
|
</packageSource>
|
||||||
|
</packageSourceMapping>
|
||||||
|
</configuration>
|
||||||
|
```
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Set up logging.
|
||||||
|
log() { echo "🛠️ $(basename $0): $@"; }
|
||||||
|
|
||||||
|
# Move into the top level.
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
./scripts/setup.sh || exit 1
|
./scripts/setup.sh || exit 1
|
||||||
|
|
||||||
echo "$(basename $0): building project"
|
log "building project"
|
||||||
dotnet build
|
dotnet build
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
npm install --ci
|
|
||||||
dotnet restore
|
|
||||||
dotnet build
|
|
|
@ -1,5 +0,0 @@
|
||||||
npm install --ci
|
|
||||||
dotnet restore
|
|
||||||
dotnet build
|
|
||||||
npm install --ci
|
|
||||||
npx semantic-release
|
|
|
@ -1,9 +0,0 @@
|
||||||
npm install --ci
|
|
||||||
npx commitlint-gitlab-ci -x @commitlint/config-conventional
|
|
||||||
dotnet restore
|
|
||||||
dotnet build
|
|
||||||
dotnet test --test-adapter-path:. --logger:"junit;LogFilePath=../artifacts/{assembly}-test-result.xml;MethodFormat=Default;FailureBodyFormat=Verbose" --collect:"XPlat Code Coverage"
|
|
||||||
dotnet new tool-manifest
|
|
||||||
dotnet tool install dotnet-reportgenerator-globaltool
|
|
||||||
dotnet tool run reportgenerator -reports:src/*/TestResults/*/coverage.cobertura.xml -targetdir:./coverage "-reporttypes:Cobertura;TextSummary"
|
|
||||||
grep "Line coverage" coverage/Summary.txt
|
|
|
@ -1,39 +1,44 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Set up logging.
|
||||||
|
log() { echo "️🚢 $(basename $0): $@"; }
|
||||||
|
|
||||||
|
# Move into the root folder and make sure we're set up.
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
./scripts/setup.sh || exit 1
|
./scripts/setup.sh || exit 1
|
||||||
|
|
||||||
# Verify the input.
|
# Verify the input.
|
||||||
if [ "x$GITEA_TOKEN" = "x" ]
|
if [ "x$GITEA_TOKEN" = "x" ]
|
||||||
then
|
then
|
||||||
echo "the environment variable GITEA_TOKEN is not defined"
|
log "the environment variable GITEA_TOKEN is not defined"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Clean up everything from the previous runs.
|
# Clean up everything from the previous runs.
|
||||||
echo "$(basename $0): cleaning project"
|
log "cleaning project"
|
||||||
dotnet clean
|
dotnet clean
|
||||||
|
|
||||||
# Version the file based on the Git repository.
|
# Version the file based on the Git repository.
|
||||||
echo "$(basename $0): setting project version"
|
log "setting project version"
|
||||||
(cd src && dotnet dotnet-gitversion /updateprojectfiles)
|
(cd src && dotnet dotnet-gitversion /updateprojectfiles)
|
||||||
SEMVER="v$(dotnet gitversion /output json | jq -r .SemVer)"
|
SEMVER="v$(dotnet gitversion /output json | jq -r .SemVer)"
|
||||||
|
|
||||||
if [ "x$SEMVER" = "x" ]
|
if [ "x$SEMVER" = "x" ]
|
||||||
then
|
then
|
||||||
echo "$(basename $0): cannot figure out the semantic version"
|
log "cannot figure out the semantic version"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build to pick up the new version.
|
# Build to pick up the new version.
|
||||||
echo "$(basename $0): building project $SEMVER"
|
log "building project $SEMVER"
|
||||||
dotnet build || exit 1
|
dotnet build || exit 1
|
||||||
|
|
||||||
# Create and publish the NuGet packages.
|
# Create and publish the NuGet packages.
|
||||||
echo "$(basename $0): creating NuGet packages"
|
log "creating NuGet packages"
|
||||||
dotnet pack -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg || exit 1
|
dotnet pack -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg || exit 1
|
||||||
|
|
||||||
echo "$(basename $0): publishing NuGet package"
|
log "publishing NuGet package"
|
||||||
dotnet nuget remove source mfgames.com >& /dev/null
|
dotnet nuget remove source mfgames.com >& /dev/null
|
||||||
dotnet nuget add source --name mfgames.com --username dmoonfire --password $GITEA_TOKEN https://src.mfgames.com/api/packages/mfgames-cil/nuget/index.json --store-password-in-clear-text || exit 1
|
dotnet nuget add source --name mfgames.com --username dmoonfire --password $GITEA_TOKEN https://src.mfgames.com/api/packages/mfgames-cil/nuget/index.json --store-password-in-clear-text || exit 1
|
||||||
dotnet nuget push --skip-duplicate --source mfgames.com src/*/bin/Debug/*.nupkg || exit 1
|
dotnet nuget push --skip-duplicate --source mfgames.com src/*/bin/Debug/*.nupkg || exit 1
|
||||||
|
@ -41,11 +46,11 @@ dotnet nuget push --skip-duplicate --source mfgames.com src/*/bin/Debug/*.nupkg
|
||||||
# Tag and push, but only if we don't have a tag.
|
# Tag and push, but only if we don't have a tag.
|
||||||
if ! git tag | grep $SEMVER >& /dev/null
|
if ! git tag | grep $SEMVER >& /dev/null
|
||||||
then
|
then
|
||||||
echo "$(basename $0): tagging and pushing"
|
log "tagging and pushing"
|
||||||
git remote add publish https://dmoonfire:$GITEA_TOKEN@src.mfgames.com/mfgames-cil/$(basename $(git config --get remote.origin.url))
|
git remote add publish https://dmoonfire:$GITEA_TOKEN@src.mfgames.com/mfgames-cil/$(basename $(git config --get remote.origin.url))
|
||||||
git tag $SEMVER
|
git tag $SEMVER
|
||||||
git push publish $SEMVER || exit 1
|
git push publish $SEMVER || exit 1
|
||||||
git remote remove publish
|
git remote remove publish
|
||||||
else
|
else
|
||||||
echo "$(basename $0): not tagging, already exists"
|
log "not tagging, already exists"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
# Set up logging.
|
||||||
|
log() { echo "📦️ $(basename $0): $@";
|
||||||
|
|
||||||
# Normalize our environment.
|
# Normalize our environment.
|
||||||
cd $(dirname $0)/..
|
cd $(dirname $0)/..
|
||||||
|
|
||||||
|
@ -8,7 +11,7 @@ for e in dotnet lefthook prettier nixfmt
|
||||||
do
|
do
|
||||||
if ! which $e >& /dev/null
|
if ! which $e >& /dev/null
|
||||||
then
|
then
|
||||||
echo "Cannot find '$e' in the path"
|
log "Cannot find '$e' in the path"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
@ -16,12 +19,12 @@ done
|
||||||
# Make sure we have lefthook is installed.
|
# Make sure we have lefthook is installed.
|
||||||
if [ ! -f .git/hooks/pre-commit ]
|
if [ ! -f .git/hooks/pre-commit ]
|
||||||
then
|
then
|
||||||
echo "$(basename $0): installing lefthook"
|
log "installing lefthook"
|
||||||
lefthook install
|
lefthook install
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Make sure our tools are installed.
|
# Make sure our tools are installed.
|
||||||
echo "$(basename $0): install .NET tools"
|
log "install .NET tools"
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
|
|
||||||
# Everything is good.
|
# Everything is good.
|
||||||
|
|
|
@ -2,6 +2,7 @@ using Markdig;
|
||||||
using Markdig.Extensions.SmartyPants;
|
using Markdig.Extensions.SmartyPants;
|
||||||
using Markdig.Parsers.Inlines;
|
using Markdig.Parsers.Inlines;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ namespace MfGames.Markdown.Gemtext.Extensions
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gemtextRenderer.ObjectRenderers
|
if (!gemtextRenderer.ObjectRenderers
|
||||||
.Contains<GemtextSmartyPantRenderer>())
|
.Contains<GemtextSmartyPantRenderer>())
|
||||||
{
|
{
|
||||||
gemtextRenderer.ObjectRenderers.Add(
|
gemtextRenderer.ObjectRenderers.Add(
|
||||||
new GemtextSmartyPantRenderer(this.Options));
|
new GemtextSmartyPantRenderer(this.Options));
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Extensions
|
namespace MfGames.Markdown.Gemtext.Extensions
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks;
|
||||||
|
|
||||||
|
@ -26,7 +27,8 @@ namespace MfGames.Markdown.Gemtext.Extensions
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var heading = gemtext.ObjectRenderers.Find<HeadingRenderer>();
|
HeadingRenderer? heading =
|
||||||
|
gemtext.ObjectRenderers.Find<HeadingRenderer>();
|
||||||
|
|
||||||
if (heading != null)
|
if (heading != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Extensions
|
namespace MfGames.Markdown.Gemtext.Extensions
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Extensions
|
namespace MfGames.Markdown.Gemtext.Extensions
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Parsers;
|
using Markdig.Parsers;
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext
|
namespace MfGames.Markdown.Gemtext
|
||||||
|
|
|
@ -1,25 +1,24 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
<Authors>Dylan Moonfire</Authors>
|
<Authors>Dylan Moonfire</Authors>
|
||||||
<Company>Moonfire Games</Company>
|
<Company>Moonfire Games</Company>
|
||||||
<RepositoryUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-gemtext-cil</RepositoryUrl>
|
<RepositoryUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-cil</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<PackageTags>ecs</PackageTags>
|
<PackageProjectUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-cil</PackageProjectUrl>
|
||||||
<PackageProjectUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-gemtext-cil</PackageProjectUrl>
|
<PackageLicense>MIT</PackageLicense>
|
||||||
<PackageLicense>MIT</PackageLicense>
|
<Description>A MarkDig extension to render Markdown in Gemtext.</Description>
|
||||||
<Description>A Markdown extension to render Markdown in Gemtext.</Description>
|
</PropertyGroup>
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ConsoleTableExt" Version="3.2.0" />
|
<PackageReference Include="ConsoleTableExt" Version="3.2.0"/>
|
||||||
<PackageReference Include="Markdig" Version="0.30.3" />
|
<PackageReference Include="Markdig" Version="0.30.3"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks
|
||||||
renderer.EnsureTwoLines();
|
renderer.EnsureTwoLines();
|
||||||
|
|
||||||
// Go through each list item and write them out.
|
// Go through each list item and write them out.
|
||||||
foreach (var item in listBlock)
|
foreach (Block? item in listBlock)
|
||||||
{
|
{
|
||||||
// If the list only contains a link, then we just render the
|
// If the list only contains a link, then we just render the
|
||||||
// link instead.
|
// link instead.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks
|
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks
|
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
using Markdig.Extensions.SmartyPants;
|
using Markdig.Extensions.SmartyPants;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines
|
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Markdig.Syntax.Inlines;
|
using Markdig.Syntax.Inlines;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines
|
namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines
|
||||||
|
@ -25,7 +26,7 @@ namespace MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines
|
||||||
// write out each link which is already formatted.
|
// write out each link which is already formatted.
|
||||||
renderer.WriteLine();
|
renderer.WriteLine();
|
||||||
|
|
||||||
foreach (var link in renderer.GatheredLinks)
|
foreach (string? link in renderer.GatheredLinks)
|
||||||
{
|
{
|
||||||
renderer.WriteLine();
|
renderer.WriteLine();
|
||||||
renderer.Write(link);
|
renderer.Write(link);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
using Markdig.Syntax.Inlines;
|
using Markdig.Syntax.Inlines;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using Markdig.Helpers;
|
using Markdig.Helpers;
|
||||||
using Markdig.Renderers;
|
using Markdig.Renderers;
|
||||||
using Markdig.Syntax;
|
using Markdig.Syntax;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Blocks;
|
||||||
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
using MfGames.Markdown.Gemtext.Renderers.Gemtext.Inlines;
|
||||||
|
|
||||||
|
|
11
src/MfGames.Markdown/Extensions/WikiLink.cs
Normal file
11
src/MfGames.Markdown/Extensions/WikiLink.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using Markdig.Syntax.Inlines;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Extensions;
|
||||||
|
|
||||||
|
public class WikiLink : LinkInline
|
||||||
|
{
|
||||||
|
public WikiLink()
|
||||||
|
{
|
||||||
|
this.IsClosed = false;
|
||||||
|
}
|
||||||
|
}
|
47
src/MfGames.Markdown/Extensions/WikiLinkExtension.cs
Normal file
47
src/MfGames.Markdown/Extensions/WikiLinkExtension.cs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
using Markdig;
|
||||||
|
using Markdig.Parsers.Inlines;
|
||||||
|
using Markdig.Renderers;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Extensions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Translate `[[Bob]]` into `/bob/`.
|
||||||
|
/// </summary>
|
||||||
|
public class WikiLinkExtension : IMarkdownExtension
|
||||||
|
{
|
||||||
|
public WikiLinkExtension()
|
||||||
|
: this(null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public WikiLinkExtension(WikiLinkOptions? options)
|
||||||
|
{
|
||||||
|
this.Options = options ?? new WikiLinkOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WikiLinkOptions Options { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Setup(MarkdownPipelineBuilder pipeline)
|
||||||
|
{
|
||||||
|
WikiLinkInlineParser? parser = pipeline.InlineParsers
|
||||||
|
.FindExact<WikiLinkInlineParser>();
|
||||||
|
|
||||||
|
if (parser != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser = new WikiLinkInlineParser(this.Options);
|
||||||
|
pipeline.InlineParsers.InsertBefore<LinkInlineParser>(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Setup(
|
||||||
|
MarkdownPipeline pipeline,
|
||||||
|
IMarkdownRenderer renderer)
|
||||||
|
{
|
||||||
|
// No setup needed here because we're using LinkInline which does the
|
||||||
|
// bulk of the work.
|
||||||
|
}
|
||||||
|
}
|
112
src/MfGames.Markdown/Extensions/WikiLinkInlineParser.cs
Normal file
112
src/MfGames.Markdown/Extensions/WikiLinkInlineParser.cs
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Markdig.Helpers;
|
||||||
|
using Markdig.Parsers;
|
||||||
|
using Markdig.Syntax.Inlines;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Extensions;
|
||||||
|
|
||||||
|
public class WikiLinkInlineParser : InlineParser
|
||||||
|
{
|
||||||
|
private readonly WikiLinkOptions options;
|
||||||
|
|
||||||
|
public WikiLinkInlineParser(WikiLinkOptions options)
|
||||||
|
{
|
||||||
|
this.options = options;
|
||||||
|
this.OpeningCharacters = new[] { '[' };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public override bool Match(
|
||||||
|
InlineProcessor processor,
|
||||||
|
ref StringSlice slice)
|
||||||
|
{
|
||||||
|
// We are looking for the `[[` opening for the tag and that the first
|
||||||
|
// one isn't escaped.
|
||||||
|
if (IsNotDelimiter(slice, '['))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to loop over the entire link, including the `[[` and `]]`
|
||||||
|
// while keeping track since we'll swallow additional characters beyond
|
||||||
|
// the link.
|
||||||
|
int linkStart = slice.Start;
|
||||||
|
int linkEnd = slice.Start;
|
||||||
|
|
||||||
|
slice.Start += 2;
|
||||||
|
|
||||||
|
// Our content starts after the double '[['.
|
||||||
|
int contentStart = slice.Start;
|
||||||
|
|
||||||
|
// We need to find the end of the link (the `]]`).
|
||||||
|
while (IsNotDelimiter(slice, ']'))
|
||||||
|
{
|
||||||
|
slice.NextChar();
|
||||||
|
linkEnd = slice.Start;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pull out the components before we adjust for the ']]' for the end.
|
||||||
|
int contentEnd = linkEnd;
|
||||||
|
|
||||||
|
// Finish skipping over the `]]`.
|
||||||
|
slice.NextChar();
|
||||||
|
slice.NextChar();
|
||||||
|
|
||||||
|
// Format the label and the URL.
|
||||||
|
string content = slice.Text.Substring(
|
||||||
|
contentStart,
|
||||||
|
contentEnd - contentStart);
|
||||||
|
string[] contentParts = content.Split('|', 2);
|
||||||
|
string label = contentParts.Last();
|
||||||
|
string url = this.options.GetUrl(contentParts.First());
|
||||||
|
|
||||||
|
// Add in any trailing components. This merges the `'s` from
|
||||||
|
// `[[Dale]]'s` into the label.
|
||||||
|
while (this.options.IsTrailingLink(slice.CurrentChar))
|
||||||
|
{
|
||||||
|
label += slice.CurrentChar;
|
||||||
|
slice.NextChar();
|
||||||
|
linkEnd++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the link that we're replacing.
|
||||||
|
WikiLink link = new()
|
||||||
|
{
|
||||||
|
Span =
|
||||||
|
{
|
||||||
|
Start = processor.GetSourcePosition(
|
||||||
|
linkStart,
|
||||||
|
out int line,
|
||||||
|
out int column),
|
||||||
|
},
|
||||||
|
Line = line,
|
||||||
|
Column = column,
|
||||||
|
Url = url,
|
||||||
|
IsClosed = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
link.AppendChild(
|
||||||
|
new LiteralInline()
|
||||||
|
{
|
||||||
|
Line = line,
|
||||||
|
Column = column,
|
||||||
|
Content = new StringSlice(label),
|
||||||
|
IsClosed = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace the inline and then indicate we have a match.
|
||||||
|
processor.Inline = link;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsNotDelimiter(
|
||||||
|
StringSlice slice,
|
||||||
|
char delimiter)
|
||||||
|
{
|
||||||
|
return slice.CurrentChar != delimiter
|
||||||
|
|| slice.PeekChar() != delimiter
|
||||||
|
|| slice.PeekCharExtra(-1) == '\\';
|
||||||
|
}
|
||||||
|
}
|
31
src/MfGames.Markdown/Extensions/WikiLinkOptions.cs
Normal file
31
src/MfGames.Markdown/Extensions/WikiLinkOptions.cs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
using Markdig.Helpers;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Extensions;
|
||||||
|
|
||||||
|
public class WikiLinkOptions
|
||||||
|
{
|
||||||
|
public WikiLinkOptions()
|
||||||
|
{
|
||||||
|
this.GetUrl = a => a;
|
||||||
|
this.IsTrailingLink = a => a.IsAlpha() || a == '\'';
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The callback to determine the link from the given wiki link. This does
|
||||||
|
/// not include trailing additions or use the label (e.g., `(ab|cd)` would
|
||||||
|
/// get `ab` as the parameters of this function.
|
||||||
|
/// </summary>
|
||||||
|
public Func<string, string> GetUrl { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <para>
|
||||||
|
/// A callback to determine if the text after the link should be merged
|
||||||
|
/// with the link label. This allows links such as [[Dale]]'s to be turned
|
||||||
|
/// into "Dale's" but pointing to "Dale" as a page.
|
||||||
|
/// </para>
|
||||||
|
/// <para>The default is to include any character or the apostrophe.</para>
|
||||||
|
/// </summary>
|
||||||
|
public Func<char, bool> IsTrailingLink { get; set; }
|
||||||
|
}
|
23
src/MfGames.Markdown/MfGames.Markdown.csproj
Normal file
23
src/MfGames.Markdown/MfGames.Markdown.csproj
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||||
|
<Authors>Dylan Moonfire</Authors>
|
||||||
|
<Company>Moonfire Games</Company>
|
||||||
|
<RepositoryUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-cil</RepositoryUrl>
|
||||||
|
<RepositoryType>Git</RepositoryType>
|
||||||
|
<PackageProjectUrl>https://gitlab.com/mfgames-cil/mfgames-markdown-cil</PackageProjectUrl>
|
||||||
|
<PackageLicense>MIT</PackageLicense>
|
||||||
|
<Description>Various extensions for MarkDig and classes for working with Markdown.</Description>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Markdig" Version="0.30.3"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -1,10 +1,11 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class CodeInlineTests
|
public class CodeInlineTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class HeaderTests
|
public class HeaderTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class ImageLinkTests
|
public class ImageLinkTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class IncreaseHeaderDepthsAfterFirstTests
|
public class IncreaseHeaderDepthsAfterFirstTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class LinkTests
|
public class LinkTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class ListTests
|
public class ListTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,26 +1,27 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<RootNamespace>MfGames.Markdown.Gemini.Tests</RootNamespace>
|
</PropertyGroup>
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1" />
|
<PackageReference Include="MfGames.TestSetup" Version="1.0.6"/>
|
||||||
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1"/>
|
||||||
<PackageReference Include="xunit" Version="2.4.2" />
|
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114"/>
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
<PackageReference Include="xunit" Version="2.4.2"/>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</PackageReference>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
</PackageReference>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
</ItemGroup>
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\src\MfGames.Markdown.Gemtext\MfGames.Markdown.Gemtext.csproj" />
|
<ProjectReference Include="..\..\src\MfGames.Markdown.Gemtext\MfGames.Markdown.Gemtext.csproj"/>
|
||||||
</ItemGroup>
|
<ProjectReference Include="..\..\src\MfGames.Markdown\MfGames.Markdown.csproj"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests the various functionality of the ParagraphLinkHandling and
|
/// Tests the various functionality of the ParagraphLinkHandling and
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class PlainTextTests
|
public class PlainTextTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests.PythonInspired
|
namespace MfGames.Markdown.Gemtext.Tests.PythonInspired
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_base_url.py
|
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_base_url.py
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests.PythonInspired
|
namespace MfGames.Markdown.Gemtext.Tests.PythonInspired
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_codeblock.py
|
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_codeblock.py
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests.PythonInspired
|
namespace MfGames.Markdown.Gemtext.Tests.PythonInspired
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_list.py
|
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_list.py
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests.PythonInspired
|
namespace MfGames.Markdown.Gemtext.Tests.PythonInspired
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs through various plain input tests.
|
/// Runs through various plain input tests.
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
using MfGames.Markdown.Gemtext.Renderers;
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests.PythonInspired
|
namespace MfGames.Markdown.Gemtext.Tests.PythonInspired
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_strip_html.py
|
/// https://github.com/makeworld-the-better-one/md2gemini/blob/master/tests/test_strip_html.py
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
using Markdig;
|
using Markdig;
|
||||||
using Markdig.Extensions.SmartyPants;
|
using Markdig.Extensions.SmartyPants;
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class QuoteTests
|
public class QuoteTests
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,12 +2,11 @@ using ConsoleTableExt;
|
||||||
|
|
||||||
using Markdig;
|
using Markdig;
|
||||||
|
|
||||||
using MfGames.Markdown.Gemtext;
|
|
||||||
using MfGames.Markdown.Gemtext.Extensions;
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace MfGames.Markdown.Gemini.Tests
|
namespace MfGames.Markdown.Gemtext.Tests
|
||||||
{
|
{
|
||||||
public class TableTests
|
public class TableTests
|
||||||
{
|
{
|
||||||
|
|
56
tests/MfGames.Markdown.Gemtext.Tests/WikiLinkTests.cs
Normal file
56
tests/MfGames.Markdown.Gemtext.Tests/WikiLinkTests.cs
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
using Markdig;
|
||||||
|
|
||||||
|
using MfGames.Markdown.Extensions;
|
||||||
|
using MfGames.Markdown.Gemtext.Extensions;
|
||||||
|
using MfGames.Markdown.Gemtext.Renderers;
|
||||||
|
using MfGames.TestSetup;
|
||||||
|
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Gemtext.Tests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the functionality of the WriteFiles().
|
||||||
|
/// </summary>
|
||||||
|
public class WikiLinkTest : TestBase<TestContext>
|
||||||
|
{
|
||||||
|
public WikiLinkTest(ITestOutputHelper output)
|
||||||
|
: base(output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PossessiveLabeledWikiLinkGemtext()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = MarkdownGemtext
|
||||||
|
.ToGemtext(
|
||||||
|
"[[Test|Label]]'s",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("=> ^test$ Label's", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MarkdownPipeline CreatePipeline()
|
||||||
|
{
|
||||||
|
// Convert all titles to slugs.
|
||||||
|
WikiLinkOptions options = new()
|
||||||
|
{
|
||||||
|
GetUrl = (title) => string.Format(
|
||||||
|
"^{0}$",
|
||||||
|
title.ToLowerInvariant().Replace(" ", "-")),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create the pipeline and return the results.
|
||||||
|
MarkdownPipelineBuilder builder = new MarkdownPipelineBuilder()
|
||||||
|
.Use(new WikiLinkExtension(options))
|
||||||
|
.Use(new SetBlockLinkHandling(BlockLinkHandling.DocumentEnd));
|
||||||
|
|
||||||
|
// Build the pipeline and return it.
|
||||||
|
MarkdownPipeline pipeline = builder.Build();
|
||||||
|
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
}
|
28
tests/MfGames.Markdown.Tests/MfGames.Markdown.Tests.csproj
Normal file
28
tests/MfGames.Markdown.Tests/MfGames.Markdown.Tests.csproj
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Markdig" Version="0.30.3"/>
|
||||||
|
<PackageReference Include="MfGames.TestSetup" Version="1.0.6"/>
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.1"/>
|
||||||
|
<PackageReference Include="JunitXml.TestLogger" Version="3.0.114"/>
|
||||||
|
<PackageReference Include="xunit" Version="2.4.2"/>
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="3.1.2">
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\MfGames.Markdown\MfGames.Markdown.csproj"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
188
tests/MfGames.Markdown.Tests/WikiLinkTests.cs
Normal file
188
tests/MfGames.Markdown.Tests/WikiLinkTests.cs
Normal file
|
@ -0,0 +1,188 @@
|
||||||
|
using Markdig;
|
||||||
|
|
||||||
|
using MfGames.Markdown.Extensions;
|
||||||
|
using MfGames.TestSetup;
|
||||||
|
|
||||||
|
using Xunit;
|
||||||
|
using Xunit.Abstractions;
|
||||||
|
|
||||||
|
namespace MfGames.Markdown.Tests;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the functionality of the WriteFiles().
|
||||||
|
/// </summary>
|
||||||
|
public class WikiLinkTest : TestBase<TestContext>
|
||||||
|
{
|
||||||
|
public WikiLinkTest(ITestOutputHelper output)
|
||||||
|
: base(output)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void BareStringHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown.ToHtml(
|
||||||
|
"This is text.",
|
||||||
|
pipeline);
|
||||||
|
|
||||||
|
Assert.Equal("<p>This is text.</p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void BlankStringHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown.ToHtml(
|
||||||
|
"",
|
||||||
|
pipeline);
|
||||||
|
|
||||||
|
Assert.Equal("", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LabeledWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test|Label]]",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Label</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PossessiveLabeledWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test|Label]]'s",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Label's</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PossessiveWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test]]'s",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Test's</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PunctuationLabeledWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test|Label]].",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Label</a>.</p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void PunctuationWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test]].",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Test</a>.</p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SentenceWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"This is a [[test]] of this system.",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal(
|
||||||
|
"<p>This is a <a href=\"^test$\">test</a> of this system.</p>\n",
|
||||||
|
result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void SimpleWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test]]",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Test</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void StandardLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown.ToHtml(
|
||||||
|
"[Test](https://test/)",
|
||||||
|
pipeline);
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"https://test/\">Test</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TrailingLabeledWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test|Label]]s",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Labels</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void TrailingWikiLinkHtml()
|
||||||
|
{
|
||||||
|
MarkdownPipeline pipeline = CreatePipeline();
|
||||||
|
string result = Markdig.Markdown
|
||||||
|
.ToHtml(
|
||||||
|
"[[Test]]s",
|
||||||
|
pipeline)
|
||||||
|
.Replace("%5E", "^");
|
||||||
|
|
||||||
|
Assert.Equal("<p><a href=\"^test$\">Tests</a></p>\n", result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MarkdownPipeline CreatePipeline()
|
||||||
|
{
|
||||||
|
WikiLinkOptions options = new()
|
||||||
|
{
|
||||||
|
GetUrl = (title) => string.Format(
|
||||||
|
"^{0}$",
|
||||||
|
title.ToLowerInvariant().Replace(" ", "-")),
|
||||||
|
};
|
||||||
|
|
||||||
|
MarkdownPipelineBuilder? builder = new MarkdownPipelineBuilder()
|
||||||
|
.Use(new WikiLinkExtension(options));
|
||||||
|
MarkdownPipeline? pipeline = builder.Build();
|
||||||
|
|
||||||
|
return pipeline;
|
||||||
|
}
|
||||||
|
}
|
Reference in a new issue