| @@ -131,7 +131,7 @@ namespace Docnet | |||
| private void GenerateSearchDataIndex() | |||
| { | |||
| var collectedSearchEntries = new List<SearchIndexEntry>(); | |||
| this.Pages.CollectSearchIndexEntries(collectedSearchEntries, new NavigatedPath()); | |||
| this.Pages.CollectSearchIndexEntries(collectedSearchEntries, new NavigatedPath(), this.PathSpecification); | |||
| JObject searchIndex = new JObject(new JProperty("docs", | |||
| new JArray( | |||
| collectedSearchEntries.Select(e=>new JObject( | |||
| @@ -164,7 +164,7 @@ namespace Docnet | |||
| searchSimpleElement.ExtraScriptProducerFunc = e=> @" | |||
| <script>var base_url = '.';</script> | |||
| <script data-main=""js/search.js"" src=""js/require.js""></script>"; | |||
| searchSimpleElement.GenerateOutput(this, activePath); | |||
| searchSimpleElement.GenerateOutput(this, activePath, this.PathSpecification); | |||
| activePath.Pop(); | |||
| } | |||
| @@ -256,6 +256,25 @@ namespace Docnet | |||
| get { return _templateContents ?? string.Empty; } | |||
| } | |||
| public PathSpecification PathSpecification | |||
| { | |||
| get | |||
| { | |||
| var pathSpecification = PathSpecification.Full; | |||
| var pathSpecificationAsString = _configData.PathSpecification; | |||
| if (!string.IsNullOrWhiteSpace(pathSpecificationAsString)) | |||
| { | |||
| if (!Enum.TryParse(pathSpecificationAsString, true, out pathSpecification)) | |||
| { | |||
| pathSpecification = PathSpecification.Full; | |||
| } | |||
| } | |||
| return pathSpecification; | |||
| } | |||
| } | |||
| public NavigationLevel Pages | |||
| { | |||
| get | |||
| @@ -60,6 +60,7 @@ | |||
| <Compile Include="NavigatedPath.cs" /> | |||
| <Compile Include="NavigationElement.cs" /> | |||
| <Compile Include="NavigationLevel.cs" /> | |||
| <Compile Include="PathSpecification.cs" /> | |||
| <Compile Include="Program.cs" /> | |||
| <Compile Include="Properties\AssemblyInfo.cs" /> | |||
| <Compile Include="SearchIndexEntry.cs" /> | |||
| @@ -70,11 +70,14 @@ namespace Docnet | |||
| Console.WriteLine("Errors occurred, can't continue!"); | |||
| return null; | |||
| } | |||
| if(config.Pages.IndexElement == null) | |||
| var indexElement = config.Pages.GetIndexElement(config.PathSpecification); | |||
| if(indexElement == null) | |||
| { | |||
| Console.WriteLine("[ERROR] Root __index not found. The root navigationlevel is required to have an __index element"); | |||
| return null; | |||
| } | |||
| return config; | |||
| } | |||
| @@ -95,7 +98,7 @@ namespace Docnet | |||
| Console.WriteLine("Copying source folders to copy."); | |||
| _loadedConfig.CopySourceFoldersToCopy(); | |||
| Console.WriteLine("Generating pages in '{0}'", _loadedConfig.Destination); | |||
| _loadedConfig.Pages.GenerateOutput(_loadedConfig, new NavigatedPath()); | |||
| _loadedConfig.Pages.GenerateOutput(_loadedConfig, new NavigatedPath(), _loadedConfig.PathSpecification); | |||
| Console.WriteLine("Generating search index"); | |||
| _loadedConfig.GenerateSearchData(); | |||
| Console.WriteLine("Done!"); | |||
| @@ -35,23 +35,31 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="activeConfig">The active configuration to use for the output.</param> | |||
| /// <param name="activePath">The active path navigated through the ToC to reach this element.</param> | |||
| void GenerateOutput(Config activeConfig, NavigatedPath activePath); | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| void GenerateOutput(Config activeConfig, NavigatedPath activePath, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Generates the ToC fragment for this element, which can either be a simple line or a full expanded menu. | |||
| /// </summary> | |||
| /// <param name="navigatedPath">The navigated path to the current element, which doesn't necessarily have to be this element.</param> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot); | |||
| string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Collects the search index entries. These are created from simple navigation elements found in this container, which aren't index element. | |||
| /// </summary> | |||
| /// <param name="collectedEntries">The collected entries.</param> | |||
| /// <param name="activePath">The active path currently navigated.</param> | |||
| void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath); | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Gets the target URL with respect to the <see cref="PathSpecification"/>. | |||
| /// </summary> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| string GetTargetURL(PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Gets a value indicating whether this element is the __index element | |||
| @@ -59,7 +67,6 @@ namespace Docnet | |||
| bool IsIndexElement { get; set; } | |||
| string Name { get; set; } | |||
| object Value { get; set; } | |||
| string TargetURL { get; } | |||
| NavigationLevel ParentContainer { get; set; } | |||
| } | |||
| } | |||
| @@ -35,17 +35,18 @@ namespace Docnet | |||
| public class NavigatedPath : Stack<INavigationElement> | |||
| { | |||
| /// <summary> | |||
| /// Creates the bread crumbs HTML of the elements in this path, delimited by '/' characters. | |||
| /// Creates the bread crumbs HTML of the elements in this path, delimited by '/' characters. | |||
| /// </summary> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public string CreateBreadCrumbsHTML(string relativePathToRoot) | |||
| public string CreateBreadCrumbsHTML(string relativePathToRoot, PathSpecification pathSpecification) | |||
| { | |||
| var fragments = new List<string>(); | |||
| // we enumerate a stack, which enumerates from top to bottom, so we have to reverse things first. | |||
| foreach(var element in this.Reverse()) | |||
| { | |||
| var targetURL = element.TargetURL; | |||
| var targetURL = element.GetTargetURL(pathSpecification); | |||
| if(string.IsNullOrWhiteSpace(targetURL)) | |||
| { | |||
| fragments.Add(string.Format("<li>{0}</li>", element.Name)); | |||
| @@ -73,11 +74,12 @@ namespace Docnet | |||
| /// <summary> | |||
| /// Creates the ToC HTML for the element reached by the elements in this path. All containers in this path are expanded, all elements inside these containers which | |||
| /// aren't, are not expanded. | |||
| /// aren't, are not expanded. | |||
| /// </summary> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public string CreateToCHTML(string relativePathToRoot) | |||
| public string CreateToCHTML(string relativePathToRoot, PathSpecification pathSpecification) | |||
| { | |||
| // the root container is the bottom element of this path. We use that container to build the root and navigate any node open along the navigated path. | |||
| var rootContainer = this.Reverse().FirstOrDefault() as NavigationLevel; | |||
| @@ -86,7 +88,7 @@ namespace Docnet | |||
| // no root container, no TOC | |||
| return string.Empty; | |||
| } | |||
| return rootContainer.GenerateToCFragment(this, relativePathToRoot); | |||
| return rootContainer.GenerateToCFragment(this, relativePathToRoot, pathSpecification); | |||
| } | |||
| } | |||
| } | |||
| @@ -36,25 +36,32 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="activeConfig">The active configuration to use for the output.</param> | |||
| /// <param name="activePath">The active path navigated through the ToC to reach this element.</param> | |||
| /// <returns>true if everything went well, false otherwise</returns> | |||
| public abstract void GenerateOutput(Config activeConfig, NavigatedPath activePath); | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| public abstract void GenerateOutput(Config activeConfig, NavigatedPath activePath, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Generates the ToC fragment for this element, which can either be a simple line or a full expanded menu. | |||
| /// </summary> | |||
| /// <param name="navigatedPath">The navigated path to the current element, which doesn't necessarily have to be this element.</param> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public abstract string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot); | |||
| public abstract string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Collects the search index entries. These are created from simple navigation elements found in this container, which aren't index element. | |||
| /// </summary> | |||
| /// <param name="collectedEntries">The collected entries.</param> | |||
| /// <param name="activePath">The active path currently navigated.</param> | |||
| public abstract void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath); | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| public abstract void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath, PathSpecification pathSpecification); | |||
| /// <summary> | |||
| /// Gets the target URL with respect to the <see cref="PathSpecification"/>. | |||
| /// </summary> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public abstract string GetTargetURL(PathSpecification pathSpecification); | |||
| #region Properties | |||
| public abstract string TargetURL { get; } | |||
| /// <summary> | |||
| /// Gets / sets a value indicating whether this element is the __index element | |||
| /// </summary> | |||
| @@ -77,20 +77,20 @@ namespace Docnet | |||
| else | |||
| { | |||
| toAdd = new SimpleNavigationElement | |||
| { | |||
| Name = nameToUse, | |||
| Value = childValue, | |||
| IsIndexElement = isIndexElement | |||
| }; | |||
| { | |||
| Name = nameToUse, | |||
| Value = childValue, | |||
| IsIndexElement = isIndexElement | |||
| }; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| var subLevel = new NavigationLevel(_rootDirectory) | |||
| { | |||
| Name = child.Key, | |||
| IsRoot = false | |||
| }; | |||
| { | |||
| Name = child.Key, | |||
| IsRoot = false | |||
| }; | |||
| subLevel.Load((JObject)child.Value); | |||
| toAdd = subLevel; | |||
| } | |||
| @@ -105,12 +105,13 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="collectedEntries">The collected entries.</param> | |||
| /// <param name="activePath">The active path currently navigated.</param> | |||
| public override void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath) | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| public override void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath, PathSpecification pathSpecification) | |||
| { | |||
| activePath.Push(this); | |||
| foreach (var element in this.Value) | |||
| { | |||
| element.CollectSearchIndexEntries(collectedEntries, activePath); | |||
| element.CollectSearchIndexEntries(collectedEntries, activePath, pathSpecification); | |||
| } | |||
| activePath.Pop(); | |||
| } | |||
| @@ -121,14 +122,15 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="activeConfig">The active configuration to use for the output.</param> | |||
| /// <param name="activePath">The active path navigated through the ToC to reach this element.</param> | |||
| public override void GenerateOutput(Config activeConfig, NavigatedPath activePath) | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| public override void GenerateOutput(Config activeConfig, NavigatedPath activePath, PathSpecification pathSpecification) | |||
| { | |||
| activePath.Push(this); | |||
| int i = 0; | |||
| while (i < this.Value.Count) | |||
| { | |||
| var element = this.Value[i]; | |||
| element.GenerateOutput(activeConfig, activePath); | |||
| element.GenerateOutput(activeConfig, activePath, pathSpecification); | |||
| i++; | |||
| } | |||
| activePath.Pop(); | |||
| @@ -140,8 +142,9 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="navigatedPath">The navigated path to the current element, which doesn't necessarily have to be this element.</param> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot) | |||
| public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, PathSpecification pathSpecification) | |||
| { | |||
| var fragments = new List<string>(); | |||
| if (!this.IsRoot) | |||
| @@ -163,7 +166,7 @@ namespace Docnet | |||
| // first render the level header, which is the index element, if present or a label. The root always has an __index element otherwise we'd have stopped at load. | |||
| var elementStartTag = "<li><span class=\"navigationgroup\"><i class=\"fa fa-caret-down\"></i> "; | |||
| var indexElement = this.IndexElement; | |||
| var indexElement = this.GetIndexElement(pathSpecification); | |||
| if (indexElement == null) | |||
| { | |||
| fragments.Add(string.Format("{0}{1}</span></li>", elementStartTag, this.Name)); | |||
| @@ -172,18 +175,18 @@ namespace Docnet | |||
| { | |||
| if (this.IsRoot) | |||
| { | |||
| fragments.Add(indexElement.PerformGenerateToCFragment(navigatedPath, relativePathToRoot)); | |||
| fragments.Add(indexElement.PerformGenerateToCFragment(navigatedPath, relativePathToRoot, pathSpecification)); | |||
| } | |||
| else | |||
| { | |||
| fragments.Add(string.Format("{0}<a href=\"{1}{2}\">{3}</a></span></li>", elementStartTag, relativePathToRoot, HttpUtility.UrlPathEncode(indexElement.TargetURL), | |||
| fragments.Add(string.Format("{0}<a href=\"{1}{2}\">{3}</a></span></li>", elementStartTag, relativePathToRoot, HttpUtility.UrlPathEncode(indexElement.GetTargetURL(pathSpecification)), | |||
| this.Name)); | |||
| } | |||
| } | |||
| // then the elements in the container. Index elements are skipped here. | |||
| foreach (var element in this.Value) | |||
| { | |||
| fragments.Add(element.GenerateToCFragment(navigatedPath, relativePathToRoot)); | |||
| fragments.Add(element.GenerateToCFragment(navigatedPath, relativePathToRoot, pathSpecification)); | |||
| } | |||
| fragments.Add("</ul>"); | |||
| } | |||
| @@ -191,7 +194,7 @@ namespace Docnet | |||
| { | |||
| // just a link | |||
| fragments.Add(string.Format("<span class=\"navigationgroup\"><i class=\"fa fa-caret-right\"></i> <a href=\"{0}{1}\">{2}</a></span>", | |||
| relativePathToRoot, HttpUtility.UrlPathEncode(this.TargetURL), this.Name)); | |||
| relativePathToRoot, HttpUtility.UrlPathEncode(this.GetTargetURL(pathSpecification)), this.Name)); | |||
| } | |||
| if (!this.IsRoot) | |||
| { | |||
| @@ -204,9 +207,9 @@ namespace Docnet | |||
| private NavigationLevel CreateGeneratedLevel(string path) | |||
| { | |||
| var root = new NavigationLevel(_rootDirectory) | |||
| { | |||
| ParentContainer = this | |||
| }; | |||
| { | |||
| ParentContainer = this | |||
| }; | |||
| foreach (var mdFile in Directory.GetFiles(path, "*.md", SearchOption.TopDirectoryOnly)) | |||
| { | |||
| @@ -217,11 +220,11 @@ namespace Docnet | |||
| } | |||
| var item = new SimpleNavigationElement | |||
| { | |||
| Name = name, | |||
| Value = Utils.MakeRelativePath(mdFile, _rootDirectory), | |||
| ParentContainer = root | |||
| }; | |||
| { | |||
| Name = name, | |||
| Value = Utils.MakeRelativePath(mdFile, _rootDirectory), | |||
| ParentContainer = root | |||
| }; | |||
| root.Value.Add(item); | |||
| } | |||
| @@ -270,49 +273,64 @@ namespace Docnet | |||
| return title; | |||
| } | |||
| #region Properties | |||
| public override string TargetURL | |||
| public override string GetTargetURL(PathSpecification pathSpecification) | |||
| { | |||
| get | |||
| var defaultElement = this.GetIndexElement(pathSpecification); | |||
| if (defaultElement == null) | |||
| { | |||
| var defaultElement = this.IndexElement; | |||
| if (defaultElement == null) | |||
| { | |||
| return string.Empty; | |||
| } | |||
| return defaultElement.TargetURL ?? string.Empty; | |||
| return string.Empty; | |||
| } | |||
| return defaultElement.GetTargetURL(pathSpecification) ?? string.Empty; | |||
| } | |||
| public SimpleNavigationElement IndexElement | |||
| public SimpleNavigationElement GetIndexElement(PathSpecification pathSpecification) | |||
| { | |||
| get | |||
| var toReturn = this.Value.FirstOrDefault(e => e.IsIndexElement) as SimpleNavigationElement; | |||
| if (toReturn == null) | |||
| { | |||
| var toReturn = this.Value.FirstOrDefault(e => e.IsIndexElement) as SimpleNavigationElement; | |||
| if (toReturn == null) | |||
| // no index element, add an artificial one. | |||
| var path = string.Empty; | |||
| if (this.ParentContainer != null) | |||
| { | |||
| // no index element, add an artificial one. | |||
| var path = string.Empty; | |||
| if (this.ParentContainer != null) | |||
| { | |||
| path = Path.GetDirectoryName(this.ParentContainer.TargetURL); | |||
| } | |||
| var nameToUse = this.Name.Replace(".", "").Replace('/', '_').Replace("\\", "_").Replace(":", "").Replace(" ", ""); | |||
| if (string.IsNullOrWhiteSpace(nameToUse)) | |||
| { | |||
| return null; | |||
| } | |||
| toReturn = new SimpleNavigationElement() { ParentContainer = this, Value = string.Format("{0}{1}.md", path, nameToUse), Name = this.Name, IsIndexElement = true }; | |||
| this.Value.Add(toReturn); | |||
| path = Path.GetDirectoryName(this.ParentContainer.GetTargetURL(pathSpecification)); | |||
| } | |||
| var nameToUse = this.Name.Replace(".", "").Replace('/', '_').Replace("\\", "_").Replace(":", "").Replace(" ", ""); | |||
| if (string.IsNullOrWhiteSpace(nameToUse)) | |||
| { | |||
| return null; | |||
| } | |||
| return toReturn; | |||
| var value = string.Empty; | |||
| switch (pathSpecification) | |||
| { | |||
| case PathSpecification.Full: | |||
| value = string.Format("{0}{1}.md", path, nameToUse); | |||
| break; | |||
| case PathSpecification.Relative: | |||
| value = Path.Combine(path ?? string.Empty, nameToUse + ".md"); | |||
| break; | |||
| default: | |||
| throw new ArgumentOutOfRangeException(nameof(pathSpecification), pathSpecification, null); | |||
| } | |||
| toReturn = new SimpleNavigationElement | |||
| { | |||
| ParentContainer = this, | |||
| Value = value, | |||
| Name = this.Name, | |||
| IsIndexElement = true | |||
| }; | |||
| this.Value.Add(toReturn); | |||
| } | |||
| } | |||
| return toReturn; | |||
| } | |||
| #region Properties | |||
| /// <summary> | |||
| /// Gets / sets a value indicating whether this element is the __index element | |||
| /// </summary> | |||
| @@ -0,0 +1,9 @@ | |||
| namespace Docnet | |||
| { | |||
| public enum PathSpecification | |||
| { | |||
| Full, | |||
| Relative | |||
| } | |||
| } | |||
| @@ -49,7 +49,9 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="activeConfig">The active configuration to use for the output.</param> | |||
| /// <param name="activePath">The active path navigated through the ToC to reach this element.</param> | |||
| public override void GenerateOutput(Config activeConfig, NavigatedPath activePath) | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <exception cref="System.IO.FileNotFoundException"></exception> | |||
| public override void GenerateOutput(Config activeConfig, NavigatedPath activePath, PathSpecification pathSpecification) | |||
| { | |||
| // if we're the __index element, we're not pushing ourselves on the path, as we're representing the container we're in, which is already on the path. | |||
| if(!this.IsIndexElement) | |||
| @@ -58,7 +60,7 @@ namespace Docnet | |||
| } | |||
| _relativeH2LinksOnPage.Clear(); | |||
| var sourceFile = Utils.MakeAbsolutePath(activeConfig.Source, this.Value); | |||
| var destinationFile = Utils.MakeAbsolutePath(activeConfig.Destination, this.TargetURL); | |||
| var destinationFile = Utils.MakeAbsolutePath(activeConfig.Destination, this.GetTargetURL(pathSpecification)); | |||
| var sb = new StringBuilder(activeConfig.PageTemplateContents.Length + 2048); | |||
| var content = string.Empty; | |||
| this.MarkdownFromFile = string.Empty; | |||
| @@ -87,7 +89,7 @@ namespace Docnet | |||
| { | |||
| continue; | |||
| } | |||
| defaultMarkdown.AppendFormat("* [{0}]({1}{2}){3}", sibling.Name, relativePathToRoot, HttpUtility.UrlPathEncode(sibling.TargetURL), Environment.NewLine); | |||
| defaultMarkdown.AppendFormat("* [{0}]({1}{2}){3}", sibling.Name, relativePathToRoot, HttpUtility.UrlPathEncode(sibling.GetTargetURL(pathSpecification)), Environment.NewLine); | |||
| } | |||
| defaultMarkdown.Append(Environment.NewLine); | |||
| content = Utils.ConvertMarkdownToHtml(defaultMarkdown.ToString(), Path.GetDirectoryName(destinationFile), activeConfig.Destination, string.Empty, _relativeH2LinksOnPage, activeConfig.ConvertLocalLinks); | |||
| @@ -109,8 +111,8 @@ namespace Docnet | |||
| sb.Replace("{{Path}}", relativePathToRoot); | |||
| sb.Replace("{{RelativeSourceFileName}}", Utils.MakeRelativePathForUri(activeConfig.Destination, sourceFile).TrimEnd('/')); | |||
| sb.Replace("{{RelativeTargetFileName}}", Utils.MakeRelativePathForUri(activeConfig.Destination, destinationFile).TrimEnd('/')); | |||
| sb.Replace("{{Breadcrumbs}}", activePath.CreateBreadCrumbsHTML(relativePathToRoot)); | |||
| sb.Replace("{{ToC}}", activePath.CreateToCHTML(relativePathToRoot)); | |||
| sb.Replace("{{Breadcrumbs}}", activePath.CreateBreadCrumbsHTML(relativePathToRoot, pathSpecification)); | |||
| sb.Replace("{{ToC}}", activePath.CreateToCHTML(relativePathToRoot, pathSpecification)); | |||
| sb.Replace("{{ExtraScript}}", (this.ExtraScriptProducerFunc == null) ? string.Empty : this.ExtraScriptProducerFunc(this)); | |||
| // the last action has to be replacing the content marker, so markers in the content which we have in the template as well aren't replaced | |||
| @@ -129,14 +131,15 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="collectedEntries">The collected entries.</param> | |||
| /// <param name="activePath">The active path currently navigated.</param> | |||
| public override void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath) | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| public override void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath, PathSpecification pathSpecification) | |||
| { | |||
| activePath.Push(this); | |||
| // simply convert ourselves into an entry if we're not an index | |||
| if(!this.IsIndexElement) | |||
| { | |||
| var toAdd = new SearchIndexEntry(); | |||
| toAdd.Fill(this.MarkdownFromFile, this.TargetURL, this.Name, activePath); | |||
| toAdd.Fill(this.MarkdownFromFile, this.GetTargetURL(pathSpecification), this.Name, activePath); | |||
| collectedEntries.Add(toAdd); | |||
| } | |||
| activePath.Pop(); | |||
| @@ -148,8 +151,9 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="navigatedPath">The navigated path to the current element, which doesn't necessarily have to be this element.</param> | |||
| /// <param name="relativePathToRoot">The relative path back to the URL root, e.g. ../.., so it can be used for links to elements in this path.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot) | |||
| public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, PathSpecification pathSpecification) | |||
| { | |||
| // index elements are rendered in the parent container. | |||
| if(this.IsIndexElement) | |||
| @@ -157,7 +161,7 @@ namespace Docnet | |||
| return string.Empty; | |||
| } | |||
| return PerformGenerateToCFragment(navigatedPath, relativePathToRoot); | |||
| return PerformGenerateToCFragment(navigatedPath, relativePathToRoot, pathSpecification); | |||
| } | |||
| @@ -167,8 +171,9 @@ namespace Docnet | |||
| /// </summary> | |||
| /// <param name="navigatedPath">The navigated path.</param> | |||
| /// <param name="relativePathToRoot">The relative path to root.</param> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| public string PerformGenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot) | |||
| public string PerformGenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot, PathSpecification pathSpecification) | |||
| { | |||
| // we can't navigate deeper from here. If we are the element being navigated to, we are the current and will have to emit any additional relative URLs too. | |||
| bool isCurrent = navigatedPath.Contains(this); | |||
| @@ -184,7 +189,7 @@ namespace Docnet | |||
| string.IsNullOrWhiteSpace(liClass) ? string.Empty : string.Format(" class=\"{0}\"", liClass), | |||
| string.IsNullOrWhiteSpace(aClass) ? string.Empty : string.Format(" class=\"{0}\"", aClass), | |||
| relativePathToRoot, | |||
| HttpUtility.UrlPathEncode(this.TargetURL), | |||
| HttpUtility.UrlPathEncode(this.GetTargetURL(pathSpecification)), | |||
| this.Name)); | |||
| if(isCurrent && _relativeH2LinksOnPage.Any()) | |||
| { | |||
| @@ -203,26 +208,27 @@ namespace Docnet | |||
| return string.Join(Environment.NewLine, fragments.ToArray()); | |||
| } | |||
| #region Properties | |||
| public override string TargetURL | |||
| /// <summary> | |||
| /// Gets the target URL with respect to the <see cref="T:Docnet.PathSpecification" />. | |||
| /// </summary> | |||
| /// <param name="pathSpecification">The path specification.</param> | |||
| /// <returns></returns> | |||
| /// <exception cref="System.NotImplementedException"></exception> | |||
| public override string GetTargetURL(PathSpecification pathSpecification) | |||
| { | |||
| get | |||
| if (_targetURLForHTML == null) | |||
| { | |||
| if(_targetURLForHTML==null) | |||
| _targetURLForHTML = (this.Value ?? string.Empty); | |||
| if (_targetURLForHTML.ToLowerInvariant().EndsWith(".md")) | |||
| { | |||
| _targetURLForHTML = (this.Value ?? string.Empty); | |||
| if(_targetURLForHTML.ToLowerInvariant().EndsWith(".md")) | |||
| { | |||
| _targetURLForHTML = _targetURLForHTML.Substring(0, _targetURLForHTML.Length-3) + ".htm"; | |||
| } | |||
| _targetURLForHTML = _targetURLForHTML.Replace("\\", "/"); | |||
| _targetURLForHTML = _targetURLForHTML.Substring(0, _targetURLForHTML.Length - 3) + ".htm"; | |||
| } | |||
| return _targetURLForHTML; | |||
| _targetURLForHTML = _targetURLForHTML.Replace("\\", "/"); | |||
| } | |||
| return _targetURLForHTML; | |||
| } | |||
| #region Properties | |||
| /// <summary> | |||
| /// Gets / sets a value indicating whether this element is the __index element | |||
| /// </summary> | |||