besm.dev
Custom C# static website generator and personal website
C#Code GenerationHTML
using static BesmDevPageHelpers;
using static PageHelpers;

public class BesmDevProject : IProject
{
    public string Name => "besm.dev";
    public string ShortDescription 
        => "Custom C# static website generator and personal website";
    public string[] Tags => new string[] { "C#", "Code Generation", "HTML", "CSS" };
    public DateTime? Date => new DateTime(2024, 3, 1);

    public HtmlElement DefineDetailsPage()
    {
        return Empty(MarkedCodeBlock(LoadThisFileAsText()[..670] + "..."),
            Paragraph("After seeing how many of my ...

After seeing how many of my previous projects were lost, I wanted to archive them somewhere and make them sharable. I didn't want to use the most recent web framework, which will likely be deprecated in a couple of years, nor did I want to work directly in JavaScript. So, I created a static website generator in C#. Using some simple operator overloading, creating content is fun and easy. I have access to all C# functionality and don't have to worry about dependencies.

Some fun features

C# types and constants will be automatically formatted and linked correctly. For example, I can call TypeLink<IList<float>>() somewhere, and it will be automatically converted to: IList<T>, uint.MaxValue.ToString() converts to: 4294967295 and DateTime.Now (at compile time) is 5/4/2024 11:14:28 AM.

The static website generator also performs C# semantic highlighting. It uses Roslyn to generate the SyntaxTree and can thus color based on the tokens. Unfortunately, this doesn't capture the rich semantic information you have in IDEs. For instance, Bla.Rot()doesn't tell you whether Bla is a class, struct, or interface, or whether Rot is a static call or instance call. While Bla.Rot() provides more useful visual information, so I allow "markings" to be added. Instead of writing InlineMarkedCodeBlock("Bla.Rot()") I write InlineMarkedCodeBlock("@class.Bla.@method.Rot()"). Unfortunately, this cannot be easily automated as it requires loading the Roslyn context of the corresponding project. It is all quite fast taking, ~0.5sec to generate this website.