josefpihrt / dotmarkdown

DotMarkdown is Markdown framework for .NET
https://josefpihrt.github.io/docs/dotmarkdown
Apache License 2.0
122 stars 9 forks source link

Unable to control escaping of common characters such as '.' and '-' which destroys plain-text readability #47

Open NameOfTheDragon opened 1 week ago

NameOfTheDragon commented 1 week ago

I'm using MarkdownWriter to render markdown into a StringBuilder. Example code:

        md.WriteStartTable(columns);
        md.WriteStartTableRow();
        foreach (var heading in columnHeadings)
        {
            md.WriteStartTableCell();
            md.WriteString(heading);
            md.WriteEndTableCell();
        }

        md.WriteEndTableRow();
        md.WriteTableHeaderSeparator();

The default escaper escapes common characters such as '.' and '-'. This destroys readability when viewing with a simple text editor such as Notepad. For example, consider this table of measurements:

Measurement    | Value   | Units        | Acceptance Criteria | Disposition
---------------|---------|--------------|---------------------|------------
Burst Duration | 458\.55 | milliseconds | Minimum 400\.00     | Pass
Power          | 2\.7651 | Volts        | Minimum 2\.0000     | Pass
Feedback Volts | 3\.2998 | Volts        | Minimum 2\.2240     | Pass
Battery level  | 6\.0077 | Volts        | Minimum 5\.0000     | Pass
Temperature    | 26\.60  | °C           |                     | Information

vs. the unescaped version:

Measurement    | Value  | Units        | Acceptance Criteria | Disposition
---------------|--------|--------------|---------------------|------------
Burst Duration | 458.55 | milliseconds | Minimum 400.00      | Pass
Power          | 2.7651 | Volts        | Minimum 2.0000      | Pass
Feedback Volts | 3.2998 | Volts        | Minimum 2.2240      | Pass
Battery level  | 6.0077 | Volts        | Minimum 5.0000      | Pass
Temperature    | 26.60  | °C           |                     | Information

Having Markdown files readable as plain text with no special software was one of the attractions of using the format, so I need to not escape any characters at all (I'm careful about what I write so this will not be an issue in my use-case). I can see there is an escaper variant called NoEscape, which seems to be exactly what I need, however I cannot find any way to inject it into the settings. The only place I can see this being set is as a default value in MarkdownBaseWriter, and my IDE says the set accessor is never used:

    protected MarkdownCharEscaper Escaper { get; set; } = MarkdownCharEscaper.Default;

Therefore, even though there are several escapers available, there seems to be no way to use anything but MarkdownCharEscaper.Default, which is DefaultMarkdownEscaper, which is too aggressive.

Would it be possible to be able to set the escaper, please? Possible via MarkdownWriterSettings?

josefpihrt commented 1 week ago

Hi,

I think it makes sense to create your own escaping rules if you want to. I don't think it makes sense to use 'no escape' everywhere. For example, you must escape '|' when you are inside a table.

Regarding the setter for MarkdownBaseWriter.Escaper, the property is set only in the class but you can implement your own writer and possibly set the Escaper from the derived class. So this is the reason why the setter is protected.

I prepared a draft PR with possible implementation of custom escaping rules.

NameOfTheDragon commented 1 week ago

I had a go at this on my own while I was waiting for you to respond, in my own fork. I got something working where I added an Escaper property to the WriterSettings, with a new .WithDefaultEscaper() method to set it. In BaseMarkdownWriter constructor I set the esacper from the settings.

It seems like in cases where escaping is mandatory, for example URLs, the writer selects and uses an appropriate escaper already, so I am only setting the default to use when no escaper is required by the writer context. It works for my use-case but I haven't thought beyond that.

I could make a pull request if you wanted, but not sure how much sense it would make because I also updated all my projects to support .netstandard2.0 and .net8.0

josefpihrt commented 1 week ago

Oh, so you want change only default escaper - when there is no specific context. Got it.

I could make a pull request if you wanted, but not sure how much sense it would make because I also updated all my projects to support .netstandard2.0 and .net8.0

PR is more than welcome. However, it would be better to not mix it changing target frameworks.