diff --git a/src/DocNet/Config.cs b/src/DocNet/Config.cs
index be71b36..f67046f 100644
--- a/src/DocNet/Config.cs
+++ b/src/DocNet/Config.cs
@@ -307,6 +307,25 @@ namespace Docnet
}
}
+ public UrlFormatting UrlFormatting
+ {
+ get
+ {
+ var urlFormatting = UrlFormatting.None;
+
+ var urlFormattingAsString = (string)_configData.UrlFormatting;
+ if (!string.IsNullOrWhiteSpace(urlFormattingAsString))
+ {
+ if (!Enum.TryParse(urlFormattingAsString, true, out urlFormatting))
+ {
+ urlFormatting = UrlFormatting.None;
+ }
+ }
+
+ return urlFormatting;
+ }
+ }
+
public NavigationLevel Pages
{
get
diff --git a/src/DocNet/Docnet.csproj b/src/DocNet/Docnet.csproj
index b2d7f24..b47e767 100644
--- a/src/DocNet/Docnet.csproj
+++ b/src/DocNet/Docnet.csproj
@@ -68,6 +68,8 @@
+
+
diff --git a/src/DocNet/Engine.cs b/src/DocNet/Engine.cs
index 6cffe93..1dff26a 100644
--- a/src/DocNet/Engine.cs
+++ b/src/DocNet/Engine.cs
@@ -45,12 +45,8 @@ namespace Docnet
return 1;
}
- var navigationContext = new NavigationContext
- {
- MaxLevel = _loadedConfig.MaxLevelInToC,
- PathSpecification = _loadedConfig.PathSpecification,
- StripIndexHtm = _loadedConfig.StripIndexHtm
- };
+ var navigationContext = new NavigationContext(_loadedConfig.PathSpecification, _loadedConfig.UrlFormatting,
+ _loadedConfig.MaxLevelInToC, _loadedConfig.StripIndexHtm);
GeneratePages(navigationContext);
return 0;
@@ -79,7 +75,8 @@ namespace Docnet
return null;
}
- var navigationContext = new NavigationContext(config.PathSpecification, config.MaxLevelInToC, config.StripIndexHtm);
+ var navigationContext = new NavigationContext(config.PathSpecification, config.UrlFormatting,
+ config.MaxLevelInToC, config.StripIndexHtm);
var indexElement = config.Pages.GetIndexElement(navigationContext);
if(indexElement == null)
diff --git a/src/DocNet/NavigationContext.cs b/src/DocNet/NavigationContext.cs
index b2e4dfb..33c891f 100644
--- a/src/DocNet/NavigationContext.cs
+++ b/src/DocNet/NavigationContext.cs
@@ -7,17 +7,20 @@
MaxLevel = 2;
}
- public NavigationContext(PathSpecification pathSpecification, int maxLevel, bool stripIndexHtm)
+ public NavigationContext(PathSpecification pathSpecification, UrlFormatting urlFormatting, int maxLevel, bool stripIndexHtm)
: this()
{
PathSpecification = pathSpecification;
- MaxLevel = maxLevel;
+ UrlFormatting = urlFormatting;
+ MaxLevel = maxLevel;
StripIndexHtm = stripIndexHtm;
}
public PathSpecification PathSpecification { get; set; }
- public int MaxLevel { get; set; }
+ public UrlFormatting UrlFormatting { get; set; }
+
+ public int MaxLevel { get; set; }
public bool StripIndexHtm { get; set; }
}
diff --git a/src/DocNet/NavigationLevel.cs b/src/DocNet/NavigationLevel.cs
index 9b30cff..73f2021 100644
--- a/src/DocNet/NavigationLevel.cs
+++ b/src/DocNet/NavigationLevel.cs
@@ -305,7 +305,20 @@ namespace Docnet
}
}
- var nameToUse = this.Name.Replace(".", "").Replace('/', '_').Replace("\\", "_").Replace(":", "").Replace(" ", "");
+ var nameToUse = string.Empty;
+
+ switch (navigationContext.UrlFormatting)
+ {
+ case UrlFormatting.None:
+ // Backwards compatibility mode
+ nameToUse = this.Name.Replace(".", "").Replace('/', '_').Replace("\\", "_").Replace(":", "").Replace(" ", "");
+ break;
+
+ default:
+ nameToUse = this.Name.ApplyUrlFormatting(navigationContext.UrlFormatting);
+ break;
+ }
+
if (string.IsNullOrWhiteSpace(nameToUse))
{
return null;
diff --git a/src/DocNet/SimpleNavigationElement.cs b/src/DocNet/SimpleNavigationElement.cs
index 55ad6df..e8722db 100644
--- a/src/DocNet/SimpleNavigationElement.cs
+++ b/src/DocNet/SimpleNavigationElement.cs
@@ -226,14 +226,18 @@ namespace Docnet
{
if (_targetURLForHTML == null)
{
- _targetURLForHTML = (this.Value ?? string.Empty);
-
- var toReplace = ".md";
+ var toReplace = "mdext";
var replacement = ".htm";
+ var value = (this.Value ?? string.Empty);
+
+ // Replace with custom extension because url formatting might optimize the extension
+ value = value.Replace(".md", toReplace);
+ _targetURLForHTML = value.ApplyUrlFormatting(navigationContext.UrlFormatting);
+
if (navigationContext.PathSpecification == PathSpecification.RelativeAsFolder)
{
- if (!IsIndexElement && !_targetURLForHTML.EndsWith("index.md", StringComparison.InvariantCultureIgnoreCase))
+ if (!IsIndexElement && !_targetURLForHTML.EndsWith($"index{toReplace}", StringComparison.InvariantCultureIgnoreCase))
{
replacement = "/index.htm";
}
diff --git a/src/DocNet/StringExtensions.cs b/src/DocNet/StringExtensions.cs
new file mode 100644
index 0000000..ebf2c41
--- /dev/null
+++ b/src/DocNet/StringExtensions.cs
@@ -0,0 +1,61 @@
+using System;
+using System.Text.RegularExpressions;
+
+namespace Docnet
+{
+ internal static class StringExtensions
+ {
+ public static string ApplyUrlFormatting(this string value, UrlFormatting urlFormatting)
+ {
+ var finalValue = string.Empty;
+ string replacementValue = null;
+
+ switch (urlFormatting)
+ {
+ case UrlFormatting.None:
+ finalValue = value;
+ break;
+
+ case UrlFormatting.Strip:
+ replacementValue = string.Empty;
+ break;
+
+ case UrlFormatting.Dashes:
+ replacementValue = "-";
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(urlFormatting), urlFormatting, null);
+ }
+
+ var splitted = value.Split(new[] { "/", "\\" }, StringSplitOptions.RemoveEmptyEntries);
+
+ if (replacementValue != null)
+ {
+ var doubleReplacementValue = replacementValue + replacementValue;
+ var regEx = new Regex("[^a-zA-Z0-9 -]");
+
+ for (var i = 0; i < splitted.Length; i++)
+ {
+ var splittedValue = splitted[i];
+
+ splittedValue = regEx.Replace(splittedValue, replacementValue).Replace(" ", replacementValue);
+
+ if (!string.IsNullOrEmpty(replacementValue))
+ {
+ while (splittedValue.Contains(doubleReplacementValue))
+ {
+ splittedValue = splittedValue.Replace(doubleReplacementValue, replacementValue);
+ }
+ }
+
+ splitted[i] = splittedValue.ToLower();
+ }
+
+ finalValue = string.Join("/", splitted);
+ }
+
+ return finalValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/DocNet/UrlFormatting.cs b/src/DocNet/UrlFormatting.cs
new file mode 100644
index 0000000..7937bb1
--- /dev/null
+++ b/src/DocNet/UrlFormatting.cs
@@ -0,0 +1,11 @@
+namespace Docnet
+{
+ public enum UrlFormatting
+ {
+ None,
+
+ Strip,
+
+ Dashes
+ }
+}
\ No newline at end of file