Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
workflow_dispatch:
inputs:
publish:
description: 'Publish to NuGet (requires NUGET_API_KEY secret)'
description: 'Publish to NuGet'
required: false
default: false
type: boolean
Expand All @@ -37,7 +37,7 @@ jobs:
shell: bash
run: |
# Base version for main branch builds
BASE_VERSION="1.0.0"
BASE_VERSION="10.0.0"

if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
# Extract version from tag (e.g., v1.2.3 -> 1.2.3)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace DemoHighlighter
{
public class Highlighter : IHighlightingPlugin
public class PythonHighlighter : IHighlightingPlugin
{
public HighlightingPluginResult Convert(List<string> lines, IElementConverter converter)
{
Expand All @@ -22,7 +22,7 @@ public HighlightingPluginResult Convert(List<string> lines, IElementConverter co
{ "number", new Regex("\\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\\b|(?:\\b\\d+(?:_\\d+)*(?:\\.(?:\\d+(?:_\\d+)*)?)?|\\B\\.\\d+(?:_\\d+)*)(?:e[+-]?\\d+(?:_\\d+)*)?j?(?!\\w)", RegexOptions.IgnoreCase)},
{ "operator", new Regex("[-+%=]=?|!=|:=|\\*\\*?=?|\\/\\/?=?|<[<=>]?|>[=>]?|[&|^~]") },
{ "punct", new Regex("[{}[\\];(),.:]") }
};
};

var theme = new Dictionary<string, Color> {
{ "comment", Color.Gray },
Expand Down
29 changes: 18 additions & 11 deletions DemoImagePlugin/DemoImagePlugin.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using VectorAi.MarkdownToPdf.Converters;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using VectorAi.MarkdownToPdf.Converters;
using VectorAi.MarkdownToPdf.Plugins;
using System.Drawing;
using System.Drawing.Imaging;

namespace DemoImagePlugin;

Expand Down Expand Up @@ -29,17 +31,22 @@ private static ImagePluginResult SomeImagePlugin()

var w = 100;
var h = 100;
using (var bitmap = new Bitmap(w, h))

// Use SixLabors.ImageSharp.Drawing for cross platform drawing
using (var image = new Image<Rgba32>(w, h))
{
bitmap.SetResolution(600, 600);
using (Graphics g = Graphics.FromImage(bitmap))
image.Metadata.HorizontalResolution = 600;
image.Metadata.VerticalResolution = 600;

image.Mutate(ctx =>
{
g.DrawLine(Pens.Black, 0, 0, w - 1, h - 1);
g.DrawLine(Pens.Black, w - 1, 0, 0, h - 1);
}
ctx.DrawLine(Color.Black, 1f, new PointF(0, 0), new PointF(w - 1, h - 1));
ctx.DrawLine(Color.Black, 1f, new PointF(w - 1, 0), new PointF(0, h - 1));
});

bitmap.Save(fileName, ImageFormat.Png);
image.SaveAsPng(fileName);
}

return new ImagePluginResult { FileName = fileName, Success = true };
}

Expand All @@ -51,7 +58,7 @@ private ImagePluginResult Math()
var fileName = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".png";
#endif

// TODO: Find a way to convert LaTeX to a PNG image
// TODO: Find a way to convert LaTeX to a PNG image that is modern and safe

return new ImagePluginResult { FileName = fileName, Success = true };
}
Expand Down
4 changes: 4 additions & 0 deletions DemoImagePlugin/DemoImagePlugin.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.7" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MarkdownToPdf\MarkdownToPdf.csproj" />
</ItemGroup>
Expand Down
8 changes: 2 additions & 6 deletions MarkdownToPdf.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
<Folder Name="/Solution Items/workflows/">
<File Path=".github/workflows/ci.yml" />
</Folder>
<Project Path="DemoHighlighter/DemoHighlighter.csproj">
<Build Project="false" />
</Project>
<Project Path="DemoImagePlugin/DemoImagePlugin.csproj">
<Build Project="false" />
</Project>
<Project Path="DemoHighlighter/DemoHighlighter.csproj" />
<Project Path="DemoImagePlugin/DemoImagePlugin.csproj" />
<Project Path="MarkdownToPdf/MarkdownToPdf.csproj" />
<Project Path="Tests/Tests.csproj" />
</Solution>
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ protected override void PrepareStyling()
{
base.PrepareStyling();

// We need to preprocess the lines and access thhe plugins now, bwcause they change the styling
// We need to preprocess the lines and access the plugins now, because they change the styling

var linesGroup = Block is FencedCodeBlock fenced ? fenced.Lines : (Block as CodeBlock)!.Lines;
var lines = new List<string>();
Expand Down
16 changes: 9 additions & 7 deletions MarkdownToPdf/MarkdownToPdf.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@
<Authors>Geert-Jan Thomas</Authors>
<Company>VectorAi</Company>
<Description>Markdown to PDF converter library using Markdig and MigraDoc/PDFsharp.</Description>
<PackageTags>markdown pdf migradoc markdig pdfsharp</PackageTags>
<PackageReadmeFile>readme.md</PackageReadmeFile>
<PackageTags>markdown pdf migradoc markdig pdfsharp .net10</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/geertjanthomas/MarkdownToPdf</RepositoryUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>

<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>

</PropertyGroup>

<ItemGroup>
<None Include="..\readme.md" Link="readme.md">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
<None Include="..\README.md" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
Expand Down
9 changes: 7 additions & 2 deletions Tests/Examples/AdvancedStyling.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,18 @@ public static void Run()

var pdf = new MarkdownToPdf();

var dingFont = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Wingdings 2" : "Webdings";
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var fontPath = Path.Join(Program.BasePath(), "data/fonts");
pdf.RegisterLocalFont("Wingdings 2", regular: "Wingdings 2.ttf");
pdf.FontDir(fontPath);
}

// definition of asterism ruler - centered decorative symbol
var asterismStyle = pdf.StyleManager.AddStyle("asterismRuler", MarkdownStyleNames.Break);
asterismStyle.Paragraph.Alignment = ParagraphAlignment.Center;
asterismStyle.Bullet.Normal.Content = "\xF9";
asterismStyle.Bullet.Normal.Font.Name = dingFont;
asterismStyle.Bullet.Normal.Font.Name = "Wingdings 2";
asterismStyle.Bullet.Normal.Font.Size = "2em";
asterismStyle.Margin.Top = 12;
asterismStyle.Margin.Bottom = 12;
Expand Down
71 changes: 44 additions & 27 deletions Tests/Examples/Features.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using VectorAi.MarkdownToPdf;
using VectorAi.MarkdownToPdf.Styling;
using MigraDoc.DocumentObjectModel;
using System.Runtime.InteropServices;

namespace Test10.Examples;

Expand All @@ -13,32 +14,48 @@ public static class Features
{
public static void Run()
{
throw new NotImplementedException();
//var filePath = Path.Join(Program.BasePath(),"data/features.md");
//var markdown = File.ReadAllText(filePath);
//var footer = "{align=center}\r\nPage [](md:page)";
//var pdf = new MarkdownToPdf();
//pdf.RegisterLocalFont("Wingdings");

//pdf.PluginManager.Add(new DemoHighlighter.Highlighter());

//// definition of custom styles used in the document
//var style = pdf.StyleManager.AddStyle("CustomListItem", MarkdownStyleNames.UnorderedListItem);
//style.Bullet.Normal.Content = "\x7B";
//style.Padding.Bottom = "12";
//style.Bullet.Normal.Font.Name = "Wingdings";

//style = pdf.StyleManager.AddStyle("NestedCustomContainer", MarkdownStyleNames.CustomContainer);
//style.Background = Colors.LightSalmon;
//pdf.StyleManager.ForElement(ElementType.CustomContainer).WithParent(ElementType.CustomContainer).Bind(style);

//pdf
// .PaperSize(PaperSize.A4)
// .FontDir("../../../data/fonts")
// .RegisterLocalFont("Roboto", regular: "Roboto-Light.ttf", bold: "Roboto-Bold.ttf", italic: "Roboto-Italic.ttf")
// .DefaultFont("Roboto", 11)
// .Add(markdown)
// .AddFooter(footer)
// .Save("features.pdf");
//throw new NotImplementedException();
var imagePath = Path.Join(Program.BasePath(), "data/images");
var fontPath = Path.Join(Program.BasePath(), "data/fonts");
var filePath = Path.Join(Program.BasePath(), "data/features.md");
var markdown = File.ReadAllText(filePath);
var footer = "{align=center}\r\nPage [](md:page)";
var pdf = new MarkdownToPdf();

pdf.PluginManager.Add(new DemoHighlighter.PythonHighlighter());

if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Default for InlineCode is Consolas but that is not cross platform available
var inlineCodeFontStyle = pdf.StyleManager.AddStyle("inlineCodeFont", MarkdownStyleNames.InlineCode);
inlineCodeFontStyle.Font.Name = "Courier New";
pdf.StyleManager.ForElement(ElementType.InlineCode).Bind(inlineCodeFontStyle);

var codeFontStyle = pdf.StyleManager.AddStyle("blockCodeFont", MarkdownStyleNames.Code);
codeFontStyle.Font.Name = "Courier New";
pdf.StyleManager.ForElement(ElementType.Code).Bind(codeFontStyle);

pdf.RegisterLocalFont("Wingdings", regular: "wingding.ttf");
}

// definition of custom styles used in the document
var style = pdf.StyleManager.AddStyle("CustomListItem", MarkdownStyleNames.UnorderedListItem);
style.Bullet.Normal.Content = "\x7B";
style.Padding.Bottom = "12";
style.Bullet.Normal.Font.Name = "Wingdings";

style = pdf.StyleManager.AddStyle("NestedCustomContainer", MarkdownStyleNames.CustomContainer);
style.Background = Colors.LightSalmon;
pdf.StyleManager.ForElement(ElementType.CustomContainer).WithParent(ElementType.CustomContainer).Bind(style);

pdf
.PaperSize(PaperSize.A4)
.ImageDir(imagePath)
.FontDir(fontPath)
.RegisterLocalFont("Roboto", regular: "Roboto-Light.ttf", bold: "Roboto-Bold.ttf", italic: "Roboto-Italic.ttf")
.DefaultFont("Roboto", 11)
.Add(markdown)
.AddFooter(footer)
.Save("features.pdf");
}
}
10 changes: 9 additions & 1 deletion Tests/Examples/FullBook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,19 @@ public static class FullBook
public static void Run()
{
var defaultFont = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "Garamond" : "Times New Roman";
var imagePath = Path.Join(Program.BasePath(), "data");
var fontPath = Path.Join(Program.BasePath(), "data/fonts");
var filePath = Path.Join(Program.BasePath(),"data/Alice.md");
var markdown = File.ReadAllText(filePath);
var footer = "{.center}\r\n[](md:page)";

var pdf = new MarkdownToPdf();

if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
pdf.RegisterLocalFont("Wingdings 2", regular: "Wingdings 2.ttf");
}

DefineStyles(pdf);

pdf.DefaultPageSetup.SectionStart = BreakType.BreakOddPage;
Expand All @@ -30,7 +37,8 @@ public static void Run()
.Title("Alice's Adventures in Wonderland")
.Author("Lewis Carroll")
.DefaultFont(defaultFont, 12)
.ImageDir("../../../data/")
.ImageDir(imagePath)
.FontDir(fontPath)
.PageMargins("2cm", "2cm", "2cm", "2.5cm")
.Add(markdown)
.AddFooter(footer)
Expand Down
30 changes: 22 additions & 8 deletions Tests/Examples/Highlighting.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Runtime.InteropServices;
using VectorAi.MarkdownToPdf;
using VectorAi.MarkdownToPdf.Styling;

namespace Test10.Examples;

Expand All @@ -10,14 +12,26 @@ public static class Highlighting
{
public static void Run()
{
throw new NotImplementedException("DemoHighlighter is not yet ported to .NET 10.");
//var filePath = Path.Join(Program.BasePath(),"data/highlighting.md");
//var markdown = File.ReadAllText(filePath);
//var pdf = new MarkdownToPdf();
//pdf.PluginManager.Add(new DemoHighlighter.Highlighter());
//pdf.WarningIssued += (o, e) => { Console.WriteLine($"{e.Category}: {e.Message}"); };
//throw new NotImplementedException("DemoHighlighter is not yet ported to .NET 10.");
var filePath = Path.Join(Program.BasePath(), "data/highlighting.md");
var markdown = File.ReadAllText(filePath);
var pdf = new MarkdownToPdf();
pdf.PluginManager.Add(new DemoHighlighter.PythonHighlighter());
pdf.WarningIssued += (o, e) => { Console.WriteLine($"{e.Category}: {e.Message}"); };

//pdf.Add(markdown)
// .Save("highlighting.pdf");
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// Default for InlineCode is Consolas but that is not cross platform available
var inlineCodeFontStyle = pdf.StyleManager.AddStyle("inlineCodeFont", MarkdownStyleNames.InlineCode);
inlineCodeFontStyle.Font.Name = "Courier New";
pdf.StyleManager.ForElement(ElementType.InlineCode).Bind(inlineCodeFontStyle);

var codeFontStyle = pdf.StyleManager.AddStyle("blockCodeFont", MarkdownStyleNames.Code);
codeFontStyle.Font.Name = "Courier New";
pdf.StyleManager.ForElement(ElementType.Code).Bind(codeFontStyle);
}

pdf.Add(markdown)
.Save("highlighting.pdf");
}
}
22 changes: 11 additions & 11 deletions Tests/Examples/Plugins.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ public static class Plugins
{
public static void Run()
{
throw new NotImplementedException();
//var dp = new DemoImagePlugin.DemoImagePlugin();
//var filePath = Path.Join(Program.BasePath(),"data/plugins.md");
//var markdown = File.ReadAllText(filePath);
//using (var pdf = new MarkdownToPdf())
//{
// pdf.PluginManager.AddMathPlugin(dp);
// pdf.WarningIssued += (o, e) => { Console.WriteLine($"{e.Category}: {e.Message}"); };
//throw new NotImplementedException();
var dp = new DemoImagePlugin.DemoImagePlugin();
var filePath = Path.Join(Program.BasePath(), "data/plugins.md");
var markdown = File.ReadAllText(filePath);
using (var pdf = new MarkdownToPdf())
{
pdf.PluginManager.AddMathPlugin(dp);
pdf.WarningIssued += (o, e) => { Console.WriteLine($"{e.Category}: {e.Message}"); };

// pdf.Add(markdown)
pdf.Add(markdown)

// .Save("plugins.pdf");
//}
.Save("plugins.pdf");
}
}
}
16 changes: 11 additions & 5 deletions Tests/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ private static void RunAllExamples()
RunSafe(Examples.Toc.Run);
RunSafe(Examples.Attributes.Run);
RunSafe(Examples.FullBook.Run);
RunSafe(Examples.Features.Run);
RunSafe(Examples.Highlighting.Run);

// Out of scope
//Examples.Features.Run();
//Examples.Highlighting.Run();
//Examples.Plugins.Run();
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
RunSafe(Examples.Plugins.Run);
}
}

private static void RunSafe(Action action)
Expand All @@ -63,7 +65,11 @@ public static string BasePath()
var cd = Environment.CurrentDirectory;
var subs = cd.Split(Path.DirectorySeparatorChar, StringSplitOptions.RemoveEmptyEntries).ToList();
var idx = subs.FindIndex(s => s == "Tests");
var basePath = $"{Path.DirectorySeparatorChar}{string.Join(Path.DirectorySeparatorChar, subs.Slice(0,idx+1))}";
var basePath = $"{string.Join(Path.DirectorySeparatorChar, subs.Slice(0, idx + 1))}";
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
basePath = $"{Path.DirectorySeparatorChar}{basePath}";
}
return basePath;
}
}
Loading