Skip to content

Commit

Permalink
feat: Add MdHeadingAnchorStyle.Auto option
Browse files Browse the repository at this point in the history
Add option MdHeadingAnchorStyle.Auto that allows to inlcude anchor tags in the output only if an anchor different from the auto-generated anchor was set.
  • Loading branch information
ap0llo committed Apr 26, 2020
1 parent 21c6383 commit 16b8a9b
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ Defines the available options for including text anchors for headings in the out
public enum MdHeadingAnchorStyle
{
None = 0,
Tag = 1
Tag = 1,
Auto = 2
}
```

**Inheritance:** object → ValueType → Enum → MdHeadingAnchorStyle

## Fields

| Name | Description |
| ---- | ----------------------------------------------------------- |
| None | Do not emit an anchor (default) |
| Tag | Include an anchor\-tag (`<a />`) for headings in the output |
| Name | Description |
| ---- | ------------------------------------------------------------------------------------------------------- |
| Auto | Include an anchor tag for heading if the heading's id is different from the automatically\-generated id |
| None | Do not emit an anchor (default) |
| Tag | Include an anchor\-tag (`<a />`) for headings in the output |

___

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ namespace Grynwald.MarkdownGenerator
{
None = 0,
Tag = 1,
Auto = 2,
}
public enum MdHeadingStyle
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,43 @@ public void Serializer_respects_HeadingAnchor_serialization_option_03()
);
}

[Fact]
public void Serializer_respects_HeadingAnchor_serialization_option_04()
{
// When HeadingAnchorStyle is 'Auto' do not include a tag if the
// id is the same as the auto generated one

var options = new MdSerializationOptions()
{
HeadingStyle = MdHeadingStyle.Atx,
HeadingAnchorStyle = MdHeadingAnchorStyle.Auto
};

AssertToStringEquals(
"## Heading\r\n",
new MdDocument(new MdHeading(2, "Heading")),
options
);
}

[Fact]
public void Serializer_respects_HeadingAnchor_serialization_option_05()
{
// When HeadingAnchorStyle is 'Auto' include a tag if the
// id is the different from the auto generated one

var options = new MdSerializationOptions()
{
HeadingStyle = MdHeadingStyle.Atx,
HeadingAnchorStyle = MdHeadingAnchorStyle.Auto
};

AssertToStringEquals(
"## <a id=\"foo\"></a> Heading\r\n",
new MdDocument(new MdHeading(2, "Heading") { Anchor = "foo" }),
options
);
}

[Theory]
[InlineData(null)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,14 @@ public void Visit(MdHeading block)
{
m_Writer.RequestBlankLine();

string anchor = "";
if (m_Options.HeadingAnchorStyle == MdHeadingAnchorStyle.Tag && !String.IsNullOrWhiteSpace(block.Anchor))
var anchor = "";
if (!String.IsNullOrWhiteSpace(block.Anchor))
{
anchor = $"<a id=\"{block.Anchor}\"></a>";
if (m_Options.HeadingAnchorStyle == MdHeadingAnchorStyle.Tag ||
(m_Options.HeadingAnchorStyle == MdHeadingAnchorStyle.Auto && !StringComparer.Ordinal.Equals(block.Anchor, block.AutoGeneratedId)))
{
anchor = $"<a id=\"{block.Anchor}\"></a>";
}
}

if (m_Options.HeadingStyle == MdHeadingStyle.Setext && block.Level <= 2)
Expand All @@ -84,7 +88,7 @@ public void Visit(MdHeading block)
if (m_Options.MaxLineLength <= 0)
{
m_Writer.WriteLine(text);
m_Writer.WriteLine(new String(underlineChar, text.Length));
m_Writer.WriteLine(new string(underlineChar, text.Length));
}
// if max line length was specified, split the value into multiple lines if necessary
else
Expand All @@ -95,7 +99,7 @@ public void Visit(MdHeading block)
{
m_Writer.WriteLine(line);
}
m_Writer.WriteLine(new String(underlineChar, headingTextLines.Max(x => x.Length)));
m_Writer.WriteLine(new string(underlineChar, headingTextLines.Max(x => x.Length)));
}
}
else
Expand Down Expand Up @@ -128,7 +132,9 @@ public void Visit(MdParagraph paragraph)

// skip paragraph if it is empty
if (lines.Length == 0)
{
return;
}

for (var i = 0; i < lines.Length; i++)
{
Expand Down Expand Up @@ -207,11 +213,15 @@ void OnBlankLineRequested(object s, EventArgs e)
// blank lines before top level lists ( = before the first item)
// should not be suppressed
if (listItemNumber == 1 && m_ListLevel == 1)
{
return;
}

// while no other line was written, suppress blank lines
if (!lineWritten)
{
m_Writer.CancelRequestBlankLine();
}
}

// event handler to update the prefix after the first line of a list item
Expand Down Expand Up @@ -242,7 +252,9 @@ void OnLineWritten(object s, EventArgs e)

// top-level lists should be surrounded by blank lines
if (m_ListLevel == 1)
{
m_Writer.RequestBlankLine();
}

m_ListLevel -= 1;
}
Expand Down
8 changes: 7 additions & 1 deletion src/MarkdownGenerator/_Model/_Blocks/MdHeading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public sealed class MdHeading : MdLeafBlock
/// </remarks>
public string? Anchor { get; set; }

/// <summary>
/// Gets the automatically generated id for this heading.
/// </summary>
internal string AutoGeneratedId { get; }


/// <summary>
/// Initializes a new instance of <see cref="MdHeading"/>
Expand Down Expand Up @@ -80,7 +85,8 @@ public MdHeading(MdSpan text, int level)

Level = level;

Anchor = HtmlUtilities.ToUrlSlug(Text.ToString());
AutoGeneratedId = HtmlUtilities.ToUrlSlug(Text.ToString());
Anchor = AutoGeneratedId;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ public enum MdHeadingAnchorStyle
/// <summary>
/// Include an anchor-tag (<c>&lt;a /&gt;</c>) for headings in the output
/// </summary>
Tag = 1
Tag = 1,

/// <summary>
/// Include an anchor tag for heading if the heading's id is different from the automatically-generated id
/// </summary>
Auto = 2
}
}

0 comments on commit 16b8a9b

Please sign in to comment.