@@ -180,7 +180,10 @@ namespace Docnet | |||
searchSimpleElement.ExtraScriptProducerFunc = (e,c,n) => @" | |||
<script>var base_url = '.';</script> | |||
<script data-main=""js/search.js"" src=""js/require.js""></script>"; | |||
searchSimpleElement.GenerateOutput(this, activePath, navigationContext); | |||
// Force custom navigation context because this should end up in the root | |||
searchSimpleElement.GenerateOutput(this, activePath, new NavigationContext(PathSpecification.Full, UrlFormatting.None, 0, false)); | |||
activePath.Pop(); | |||
} | |||
@@ -16,12 +16,23 @@ namespace Docnet | |||
public static string GetFinalTargetUrl(this INavigationElement navigationElement, NavigationContext navigationContext) | |||
{ | |||
var targetUrl = navigationElement.GetTargetURL(navigationContext); | |||
return GetFinalTargetUrl(targetUrl, navigationContext); | |||
} | |||
/// <summary> | |||
/// Gets the final URL by encoding the path and by removing the filename if it equals <c>index.htm</c>. | |||
/// </summary> | |||
/// <param name="targetUrl">The target URL.</param> | |||
/// <param name="navigationContext">The navigation context.</param> | |||
/// <returns></returns> | |||
public static string GetFinalTargetUrl(this string targetUrl, NavigationContext navigationContext) | |||
{ | |||
var link = HttpUtility.UrlPathEncode(targetUrl); | |||
if (navigationContext.StripIndexHtm) | |||
{ | |||
if (link.Length > IndexHtmFileName.Length && | |||
link.EndsWith(IndexHtmFileName, StringComparison.InvariantCultureIgnoreCase)) | |||
link.EndsWith(IndexHtmFileName, StringComparison.InvariantCultureIgnoreCase)) | |||
{ | |||
link = link.Substring(0, link.Length - IndexHtmFileName.Length); | |||
} | |||
@@ -42,7 +42,8 @@ namespace Docnet | |||
var destinationFile = Utils.MakeAbsolutePath(config.Destination, this.GetTargetURL(navigationContext)); | |||
var htmlContent = Utils.ConvertMarkdownToHtml(markdownContent, Path.GetDirectoryName(destinationFile), config.Destination, | |||
string.Empty, new List<Heading>(), config.ConvertLocalLinks); | |||
string.Empty, new List<Heading>(), config.ConvertLocalLinks, | |||
new NavigationContext(config.PathSpecification, config.UrlFormatting, config.MaxLevelInToC, config.StripIndexHtm)); | |||
return htmlContent; | |||
} | |||
@@ -72,7 +72,7 @@ namespace Docnet | |||
this.MarkdownFromFile = File.ReadAllText(sourceFile, Encoding.UTF8); | |||
// Check if the content contains @@include tag | |||
content = Utils.IncludeProcessor(this.MarkdownFromFile, Utils.MakeAbsolutePath(activeConfig.Source, activeConfig.IncludeFolder)); | |||
content = Utils.ConvertMarkdownToHtml(content, Path.GetDirectoryName(destinationFile), activeConfig.Destination, sourceFile, _relativeLinksOnPage, activeConfig.ConvertLocalLinks); | |||
content = Utils.ConvertMarkdownToHtml(content, Path.GetDirectoryName(destinationFile), activeConfig.Destination, sourceFile, _relativeLinksOnPage, activeConfig.ConvertLocalLinks, navigationContext); | |||
} | |||
else | |||
{ | |||
@@ -95,7 +95,7 @@ namespace Docnet | |||
sibling.GetFinalTargetUrl(navigationContext), Environment.NewLine); | |||
} | |||
defaultMarkdown.Append(Environment.NewLine); | |||
content = Utils.ConvertMarkdownToHtml(defaultMarkdown.ToString(), Path.GetDirectoryName(destinationFile), activeConfig.Destination, string.Empty, _relativeLinksOnPage, activeConfig.ConvertLocalLinks); | |||
content = Utils.ConvertMarkdownToHtml(defaultMarkdown.ToString(), Path.GetDirectoryName(destinationFile), activeConfig.Destination, string.Empty, _relativeLinksOnPage, activeConfig.ConvertLocalLinks, navigationContext); | |||
} | |||
else | |||
{ | |||
@@ -112,7 +112,7 @@ namespace Docnet | |||
sb.Replace("{{Footer}}", activeConfig.Footer); | |||
sb.Replace("{{TopicTitle}}", this.Name); | |||
sb.Replace("{{Path}}", relativePathToRoot); | |||
sb.Replace("{{RelativeSourceFileName}}", Utils.MakeRelativePathForUri(activeConfig.Destination, sourceFile).TrimEnd('/')); | |||
sb.Replace("{{RelativeSourceFileName}}", Utils.MakeRelativePathForUri(activeConfig.Source, sourceFile).TrimEnd('/')); | |||
sb.Replace("{{RelativeTargetFileName}}", Utils.MakeRelativePathForUri(activeConfig.Destination, destinationFile).TrimEnd('/')); | |||
sb.Replace("{{Breadcrumbs}}", activePath.CreateBreadCrumbsHTML(relativePathToRoot, navigationContext)); | |||
sb.Replace("{{ToC}}", activePath.CreateToCHTML(relativePathToRoot, navigationContext)); | |||
@@ -226,29 +226,7 @@ namespace Docnet | |||
{ | |||
if (_targetURLForHTML == null) | |||
{ | |||
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{toReplace}", StringComparison.InvariantCultureIgnoreCase)) | |||
{ | |||
replacement = "/index.htm"; | |||
} | |||
} | |||
if (_targetURLForHTML.EndsWith(toReplace, StringComparison.InvariantCultureIgnoreCase)) | |||
{ | |||
_targetURLForHTML = _targetURLForHTML.Substring(0, _targetURLForHTML.Length - toReplace.Length) + replacement; | |||
} | |||
_targetURLForHTML = _targetURLForHTML.Replace("\\", "/"); | |||
_targetURLForHTML = Utils.ResolveTargetURL(this.Value ?? string.Empty, IsIndexElement, navigationContext); | |||
} | |||
return _targetURLForHTML; | |||
@@ -37,6 +37,11 @@ namespace Docnet | |||
for(var i = 0; i < splitted.Length; i++) | |||
{ | |||
var splittedValue = splitted[i]; | |||
if (string.Equals(splittedValue, ".") || string.Equals(splittedValue, "..")) | |||
{ | |||
continue; | |||
} | |||
splittedValue = regEx.Replace(splittedValue, replacementValue).Replace(" ", replacementValue); | |||
if (!string.IsNullOrEmpty(replacementValue)) | |||
@@ -1,9 +1,9 @@ | |||
namespace Docnet | |||
{ | |||
public enum UrlFormatting | |||
{ | |||
public enum UrlFormatting | |||
{ | |||
None, | |||
Strip, | |||
Dashes | |||
} | |||
Strip, | |||
Dashes | |||
} | |||
} |
@@ -38,34 +38,70 @@ namespace Docnet | |||
/// Regex expression used to parse @@include(filename.html) tag. | |||
/// </summary> | |||
private static Regex includeRegex = new Regex(@"@@include\((.*)\)", RegexOptions.IgnoreCase | RegexOptions.Compiled); | |||
#endregion | |||
/// <summary> | |||
/// Converts the markdown to HTML. | |||
/// </summary> | |||
/// <param name="toConvert">The markdown string to convert.</param> | |||
/// <param name="destinationDocumentPath">The document path (without the document filename).</param> | |||
/// <param name="siteRoot">The site root.</param> | |||
/// <param name="sourceDocumentFilename">the filename of the source markdown file</param> | |||
/// <param name="createdAnchorCollector">The created anchor collector, for ToC sublinks for H2 headers.</param> | |||
/// <param name="convertLocalLinks">if set to <c>true</c>, convert local links to md files to target files.</param> | |||
/// <returns></returns> | |||
public static string ConvertMarkdownToHtml(string toConvert, string destinationDocumentPath, string siteRoot, string sourceDocumentFilename, | |||
List<Heading> createdAnchorCollector, bool convertLocalLinks) | |||
#endregion | |||
/// <summary> | |||
/// Converts the markdown to HTML. | |||
/// </summary> | |||
/// <param name="toConvert">The markdown string to convert.</param> | |||
/// <param name="destinationDocumentPath">The document path (without the document filename).</param> | |||
/// <param name="siteRoot">The site root.</param> | |||
/// <param name="sourceDocumentFilename">the filename of the source markdown file</param> | |||
/// <param name="createdAnchorCollector">The created anchor collector, for ToC sublinks for H2 headers.</param> | |||
/// <param name="convertLocalLinks">if set to <c>true</c>, convert local links to md files to target files.</param> | |||
/// <param name="navigationContext">The navigation context.</param> | |||
/// <returns></returns> | |||
public static string ConvertMarkdownToHtml(string toConvert, string destinationDocumentPath, string siteRoot, string sourceDocumentFilename, | |||
List<Heading> createdAnchorCollector, bool convertLocalLinks, NavigationContext navigationContext) | |||
{ | |||
var localLinkProcessor = new Func<string, string>(s => | |||
{ | |||
var result = s; | |||
if (!string.IsNullOrWhiteSpace(result)) | |||
{ | |||
switch (navigationContext.PathSpecification) | |||
{ | |||
case PathSpecification.Full: | |||
break; | |||
case PathSpecification.Relative: | |||
break; | |||
case PathSpecification.RelativeAsFolder: | |||
// Step 1: we need to move up 1 additional folder (get out of current subfolder) | |||
var relativeAsFolderIndex = result.StartsWith("./") ? 2 : 0; | |||
result = result.Insert(relativeAsFolderIndex, "../"); | |||
// Step 2: we need an additional layer to go into (filename is now a folder) | |||
result = ResolveTargetURL(result, false, navigationContext); | |||
// Step 3: get the final url | |||
result = result.GetFinalTargetUrl(navigationContext); | |||
break; | |||
default: | |||
throw new ArgumentOutOfRangeException(nameof(navigationContext.PathSpecification), navigationContext.PathSpecification, null); | |||
} | |||
} | |||
return result; | |||
}); | |||
var parser = new MarkdownDeep.Markdown | |||
{ | |||
ExtraMode = true, | |||
GitHubCodeBlocks = true, | |||
AutoHeadingIDs = true, | |||
NewWindowForExternalLinks = true, | |||
DocNetMode = true, | |||
ConvertLocalLinks = convertLocalLinks, | |||
DestinationDocumentLocation = destinationDocumentPath, | |||
DocumentRoot = siteRoot, | |||
SourceDocumentFilename = sourceDocumentFilename, | |||
HtmlClassTitledImages = "figure", | |||
}; | |||
{ | |||
ExtraMode = true, | |||
GitHubCodeBlocks = true, | |||
AutoHeadingIDs = true, | |||
NewWindowForExternalLinks = true, | |||
DocNetMode = true, | |||
ConvertLocalLinks = convertLocalLinks, | |||
LocalLinkProcessor = localLinkProcessor, | |||
DestinationDocumentLocation = destinationDocumentPath, | |||
DocumentRoot = siteRoot, | |||
SourceDocumentFilename = sourceDocumentFilename, | |||
HtmlClassTitledImages = "figure", | |||
}; | |||
var toReturn = parser.Transform(toConvert); | |||
@@ -74,6 +110,33 @@ namespace Docnet | |||
return toReturn; | |||
} | |||
public static string ResolveTargetURL(string sourceFileName, bool isIndexElement, NavigationContext navigationContext) | |||
{ | |||
var toReplace = "mdext"; | |||
var replacement = ".htm"; | |||
var value = sourceFileName; | |||
// Replace with custom extension because url formatting might optimize the extension | |||
value = value.Replace(".md", toReplace); | |||
var targetUrl = value.ApplyUrlFormatting(navigationContext.UrlFormatting); | |||
if (navigationContext.PathSpecification == PathSpecification.RelativeAsFolder) | |||
{ | |||
if (!isIndexElement && !targetUrl.EndsWith($"index{toReplace}", StringComparison.InvariantCultureIgnoreCase)) | |||
{ | |||
replacement = "/index.htm"; | |||
} | |||
} | |||
if (targetUrl.EndsWith(toReplace, StringComparison.InvariantCultureIgnoreCase)) | |||
{ | |||
targetUrl = targetUrl.Substring(0, targetUrl.Length - toReplace.Length) + replacement; | |||
} | |||
targetUrl = targetUrl.Replace("\\", "/"); | |||
return targetUrl; | |||
} | |||
/// <summary> | |||
/// Copies directories and files, eventually recursively. From MSDN. | |||
@@ -85,26 +148,26 @@ namespace Docnet | |||
{ | |||
// Get the subdirectories for the specified directory. | |||
DirectoryInfo sourceFolder = new DirectoryInfo(sourceFolderName); | |||
if(!sourceFolder.Exists) | |||
if (!sourceFolder.Exists) | |||
{ | |||
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " + sourceFolderName); | |||
} | |||
DirectoryInfo[] sourceFoldersToCopy = sourceFolder.GetDirectories(); | |||
// If the destination directory doesn't exist, create it. | |||
if(!Directory.Exists(destinationFolderName)) | |||
if (!Directory.Exists(destinationFolderName)) | |||
{ | |||
Directory.CreateDirectory(destinationFolderName); | |||
} | |||
// Get the files in the directory and copy them to the new location. | |||
foreach(FileInfo file in sourceFolder.GetFiles()) | |||
foreach (FileInfo file in sourceFolder.GetFiles()) | |||
{ | |||
file.CopyTo(Path.Combine(destinationFolderName, file.Name), true); | |||
} | |||
if(copySubFolders) | |||
if (copySubFolders) | |||
{ | |||
foreach(DirectoryInfo subFolder in sourceFoldersToCopy) | |||
foreach (DirectoryInfo subFolder in sourceFoldersToCopy) | |||
{ | |||
Utils.DirectoryCopy(subFolder.FullName, Path.Combine(destinationFolderName, subFolder.Name), copySubFolders); | |||
} | |||
@@ -121,11 +184,11 @@ namespace Docnet | |||
/// <returns></returns> | |||
public static string MakeAbsolutePath(string rootPath, string toMakeAbsolute) | |||
{ | |||
if(string.IsNullOrWhiteSpace(toMakeAbsolute)) | |||
if (string.IsNullOrWhiteSpace(toMakeAbsolute)) | |||
{ | |||
return rootPath; | |||
} | |||
if(Path.IsPathRooted(toMakeAbsolute)) | |||
if (Path.IsPathRooted(toMakeAbsolute)) | |||
{ | |||
return toMakeAbsolute; | |||
} | |||
@@ -141,12 +204,12 @@ namespace Docnet | |||
public static void CreateFoldersIfRequired(string fullPath) | |||
{ | |||
string folderToCheck = Path.GetDirectoryName(fullPath); | |||
if(string.IsNullOrWhiteSpace(folderToCheck)) | |||
if (string.IsNullOrWhiteSpace(folderToCheck)) | |||
{ | |||
// nothing to do, no folder to emit | |||
return; | |||
} | |||
if(!Directory.Exists(folderToCheck)) | |||
if (!Directory.Exists(folderToCheck)) | |||
{ | |||
Directory.CreateDirectory(folderToCheck); | |||
} | |||
@@ -163,20 +226,20 @@ namespace Docnet | |||
public static string MakeRelativePath(string fromPath, string toPath) | |||
{ | |||
var fromPathToUse = fromPath; | |||
if(string.IsNullOrEmpty(fromPathToUse)) | |||
if (string.IsNullOrEmpty(fromPathToUse)) | |||
{ | |||
return string.Empty; | |||
} | |||
var toPathToUse = toPath; | |||
if(string.IsNullOrEmpty(toPathToUse)) | |||
if (string.IsNullOrEmpty(toPathToUse)) | |||
{ | |||
return string.Empty; | |||
} | |||
if(fromPathToUse.Last() != Path.DirectorySeparatorChar) | |||
if (fromPathToUse.Last() != Path.DirectorySeparatorChar) | |||
{ | |||
fromPathToUse += Path.DirectorySeparatorChar; | |||
} | |||
if(toPathToUse.Last() != Path.DirectorySeparatorChar) | |||
if (toPathToUse.Last() != Path.DirectorySeparatorChar) | |||
{ | |||
toPathToUse += Path.DirectorySeparatorChar; | |||
} | |||
@@ -184,7 +247,7 @@ namespace Docnet | |||
var fromUri = new Uri(Uri.UnescapeDataString(Path.GetFullPath(fromPathToUse))); | |||
var toUri = new Uri(Uri.UnescapeDataString(Path.GetFullPath(toPathToUse))); | |||
if(fromUri.Scheme != toUri.Scheme) | |||
if (fromUri.Scheme != toUri.Scheme) | |||
{ | |||
// path can't be made relative. | |||
return toPathToUse; | |||
@@ -193,7 +256,7 @@ namespace Docnet | |||
var relativeUri = fromUri.MakeRelativeUri(toUri); | |||
string relativePath = Uri.UnescapeDataString(relativeUri.ToString()); | |||
if(toUri.Scheme.ToUpperInvariant() == "FILE") | |||
if (toUri.Scheme.ToUpperInvariant() == "FILE") | |||
{ | |||
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); | |||
} | |||
@@ -242,5 +305,5 @@ namespace Docnet | |||
} | |||
return content; | |||
} | |||
} | |||
} | |||
} |
@@ -58,24 +58,32 @@ namespace MarkdownDeep | |||
{ | |||
HtmlTag tag = new HtmlTag("a"); | |||
var url = this.Url; | |||
if (m.DocNetMode && m.ConvertLocalLinks) | |||
{ | |||
// A few requirements before we can convert local links: | |||
// 1. Link contains .md | |||
// 2. Link is relative | |||
// 3. Link is included in the index | |||
var index = url.LastIndexOf(".md", StringComparison.OrdinalIgnoreCase); | |||
if (index >= 0) | |||
{ | |||
Uri uri; | |||
if(Uri.TryCreate(url, UriKind.Relative, out uri)) | |||
var url = this.Url; | |||
if (m.DocNetMode && m.ConvertLocalLinks) | |||
{ | |||
// A few requirements before we can convert local links: | |||
// 1. Link contains .md | |||
// 2. Link is relative | |||
// 3. Link is included in the index | |||
var index = url.LastIndexOf(".md", StringComparison.OrdinalIgnoreCase); | |||
if (index >= 0) | |||
{ | |||
var linkProcessor = m.LocalLinkProcessor; | |||
if (linkProcessor != null) | |||
{ | |||
url = linkProcessor(url); | |||
} | |||
else | |||
{ | |||
url = String.Concat(url.Substring(0, index), ".htm", url.Substring(index + ".md".Length)); | |||
Uri uri; | |||
if (Uri.TryCreate(url, UriKind.Relative, out uri)) | |||
{ | |||
url = String.Concat(url.Substring(0, index), ".htm", url.Substring(index + ".md".Length)); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
// encode url | |||
StringBuilder sb = m.GetStringBuilder(); | |||
@@ -83,14 +91,14 @@ namespace MarkdownDeep | |||
tag.attributes["href"] = sb.ToString(); | |||
// encode title | |||
if (!String.IsNullOrEmpty(this.Title )) | |||
if (!String.IsNullOrEmpty(this.Title)) | |||
{ | |||
sb.Length = 0; | |||
Utils.SmartHtmlEncodeAmpsAndAngles(sb, this.Title); | |||
tag.attributes["title"] = sb.ToString(); | |||
} | |||
if(specialAttributes.Any()) | |||
if (specialAttributes.Any()) | |||
{ | |||
LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag); | |||
} | |||
@@ -101,7 +109,7 @@ namespace MarkdownDeep | |||
// Render the opening tag | |||
tag.RenderOpening(b); | |||
b.Append(link_text); // Link text already escaped by SpanFormatter | |||
b.Append(link_text); // Link text already escaped by SpanFormatter | |||
b.Append("</a>"); | |||
} | |||
} | |||
@@ -131,7 +139,7 @@ namespace MarkdownDeep | |||
Utils.SmartHtmlEncodeAmpsAndAngles(sb, Title); | |||
tag.attributes["title"] = sb.ToString(); | |||
} | |||
if(specialAttributes.Any()) | |||
if (specialAttributes.Any()) | |||
{ | |||
LinkDefinition.HandleSpecialAttributes(specialAttributes, sb, tag); | |||
} | |||
@@ -153,9 +161,9 @@ namespace MarkdownDeep | |||
// Parse a link definition | |||
internal static LinkDefinition ParseLinkDefinition(StringScanner p, bool ExtraMode) | |||
{ | |||
int savepos=p.Position; | |||
int savepos = p.Position; | |||
var l = ParseLinkDefinitionInternal(p, ExtraMode); | |||
if (l==null) | |||
if (l == null) | |||
p.Position = savepos; | |||
return l; | |||
@@ -181,7 +189,7 @@ namespace MarkdownDeep | |||
return null; | |||
// Parse the url and title | |||
var link=ParseLinkTarget(p, id, ExtraMode); | |||
var link = ParseLinkTarget(p, id, ExtraMode); | |||
// and trailing whitespace | |||
p.SkipLinespace(); | |||
@@ -236,7 +244,7 @@ namespace MarkdownDeep | |||
int paren_depth = 1; | |||
while (!p.Eol) | |||
{ | |||
char ch=p.Current; | |||
char ch = p.Current; | |||
if (char.IsWhiteSpace(ch)) | |||
break; | |||
if (id == null) | |||
@@ -246,7 +254,7 @@ namespace MarkdownDeep | |||
else if (ch == ')') | |||
{ | |||
paren_depth--; | |||
if (paren_depth==0) | |||
if (paren_depth == 0) | |||
break; | |||
} | |||
} | |||
@@ -275,7 +283,7 @@ namespace MarkdownDeep | |||
char delim; | |||
switch (p.Current) | |||
{ | |||
case '\'': | |||
case '\'': | |||
case '\"': | |||
delim = p.Current; | |||
break; | |||
@@ -349,27 +357,27 @@ namespace MarkdownDeep | |||
private static void HandleSpecialAttributes(List<string> specialAttributes, StringBuilder sb, HtmlTag tag) | |||
{ | |||
string id = specialAttributes.FirstOrDefault(s => s.StartsWith("#")); | |||
if(id != null && id.Length > 1) | |||
if (id != null && id.Length > 1) | |||
{ | |||
sb.Length = 0; | |||
Utils.SmartHtmlEncodeAmpsAndAngles(sb, id.Substring(1)); | |||
tag.attributes["id"] = sb.ToString(); | |||
} | |||
var cssClasses = new List<string>(); | |||
foreach(var cssClass in specialAttributes.Where(s => s.StartsWith(".") && s.Length > 1)) | |||
foreach (var cssClass in specialAttributes.Where(s => s.StartsWith(".") && s.Length > 1)) | |||
{ | |||
sb.Length = 0; | |||
Utils.SmartHtmlEncodeAmpsAndAngles(sb, cssClass.Substring(1)); | |||
cssClasses.Add(sb.ToString()); | |||
} | |||
if(cssClasses.Any()) | |||
if (cssClasses.Any()) | |||
{ | |||
tag.attributes["class"] = string.Join(" ", cssClasses.ToArray()); | |||
} | |||
foreach(var nameValuePair in specialAttributes.Where(s => s.Contains("=") && s.Length > 2 && !s.StartsWith(".") && !s.StartsWith("#"))) | |||
foreach (var nameValuePair in specialAttributes.Where(s => s.Contains("=") && s.Length > 2 && !s.StartsWith(".") && !s.StartsWith("#"))) | |||
{ | |||
var pair = nameValuePair.Split('='); | |||
if(pair.Length == 2) | |||
if (pair.Length == 2) | |||
{ | |||
sb.Length = 0; | |||
Utils.SmartHtmlEncodeAmpsAndAngles(sb, pair[0]); | |||
@@ -880,6 +880,14 @@ namespace MarkdownDeep | |||
/// </summary> | |||
public bool ConvertLocalLinks { get; set; } | |||
/// <summary> | |||
/// Gets or sets the local link processor allowing customization of the local links before being transformed. | |||
/// </summary> | |||
/// <value> | |||
/// The local link processor. | |||
/// </value> | |||
public Func<string, string> LocalLinkProcessor { get; set; } | |||
// When set, all html block level elements automatically support | |||
// markdown syntax within them. | |||
// (Similar to Pandoc's handling of markdown in html) | |||