Browse Source

Merge branch 'GeertvanHorrik-pr/wildcard-inclusions'

pull/61/merge
Frans Bouma 8 years ago
parent
commit
f18083fc6f
2 changed files with 129 additions and 24 deletions
  1. +1
    -1
      src/DocNet/Config.cs
  2. +128
    -23
      src/DocNet/NavigationLevel.cs

+ 1
- 1
src/DocNet/Config.cs View File

@@ -263,7 +263,7 @@ namespace Docnet
if(_pages == null)
{
JObject rawPages = _configData.Pages;
_pages = new NavigationLevel() {Name = "Home", IsRoot = true};
_pages = new NavigationLevel(Source) {Name = "Home", IsRoot = true};
_pages.Load(rawPages);
}
return _pages;


+ 128
- 23
src/DocNet/NavigationLevel.cs View File

@@ -33,30 +33,64 @@ namespace Docnet
{
public class NavigationLevel : NavigationElement<List<INavigationElement>>
{
public NavigationLevel() : base()
#region Members
private readonly string _rootDirectory;
#endregion

public NavigationLevel(string rootDirectory)
: base()
{
this._rootDirectory = rootDirectory;
this.Value = new List<INavigationElement>();
}


public void Load(JObject dataFromFile)
{
foreach(KeyValuePair<string, JToken> child in dataFromFile)
foreach (KeyValuePair<string, JToken> child in dataFromFile)
{
INavigationElement toAdd;
if(child.Value.Type == JTokenType.String)
if (child.Value.Type == JTokenType.String)
{
var nameToUse = child.Key;

var isIndexElement = child.Key == "__index";
if(isIndexElement)
if (isIndexElement)
{
nameToUse = this.Name;
}
toAdd = new SimpleNavigationElement() { Name = nameToUse, Value = child.Value.ToObject<string>(), IsIndexElement = isIndexElement};

var childValue = child.Value.ToObject<string>();
if (childValue.EndsWith("**"))
{
var path = childValue.Replace("**", string.Empty)
.Replace('\\', Path.DirectorySeparatorChar)
.Replace('/', Path.DirectorySeparatorChar);

if (!Path.IsPathRooted(path))
{
path = Path.Combine(_rootDirectory, path);
}
toAdd = CreateGeneratedLevel(path);
toAdd.Name = nameToUse;
}
else
{
toAdd = new SimpleNavigationElement
{
Name = nameToUse,
Value = childValue,
IsIndexElement = isIndexElement
};
}
}
else
{
var subLevel = new NavigationLevel() { Name = child.Key, IsRoot = false};
var subLevel = new NavigationLevel(_rootDirectory)
{
Name = child.Key,
IsRoot = false
};
subLevel.Load((JObject)child.Value);
toAdd = subLevel;
}
@@ -74,7 +108,7 @@ namespace Docnet
public override void CollectSearchIndexEntries(List<SearchIndexEntry> collectedEntries, NavigatedPath activePath)
{
activePath.Push(this);
foreach(var element in this.Value)
foreach (var element in this.Value)
{
element.CollectSearchIndexEntries(collectedEntries, activePath);
}
@@ -91,7 +125,7 @@ namespace Docnet
{
activePath.Push(this);
int i = 0;
while(i<this.Value.Count)
while (i < this.Value.Count)
{
var element = this.Value[i];
element.GenerateOutput(activeConfig, activePath);
@@ -110,15 +144,15 @@ namespace Docnet
public override string GenerateToCFragment(NavigatedPath navigatedPath, string relativePathToRoot)
{
var fragments = new List<string>();
if(!this.IsRoot)
if (!this.IsRoot)
{
fragments.Add("<li class=\"tocentry\">");
}
if(navigatedPath.Contains(this))
if (navigatedPath.Contains(this))
{
// we're expanded. If we're not root and on the top of the navigated path stack, our index page is the page we're currently generating the ToC for, so
// we have to mark the entry as 'current'
if(navigatedPath.Peek() == this && !this.IsRoot)
if (navigatedPath.Peek() == this && !this.IsRoot)
{
fragments.Add("<ul class=\"current\">");
}
@@ -130,24 +164,24 @@ 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;
if(indexElement == null)
if (indexElement == null)
{
fragments.Add(string.Format("{0}{1}</span></li>", elementStartTag, this.Name));
}
else
{
if(this.IsRoot)
if (this.IsRoot)
{
fragments.Add(indexElement.PerformGenerateToCFragment(navigatedPath, relativePathToRoot));
}
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.TargetURL),
this.Name));
}
}
// then the elements in the container. Index elements are skipped here.
foreach(var element in this.Value)
foreach (var element in this.Value)
{
fragments.Add(element.GenerateToCFragment(navigatedPath, relativePathToRoot));
}
@@ -156,10 +190,10 @@ namespace Docnet
else
{
// just a link
fragments.Add(string.Format("<span class=\"navigationgroup\"><i class=\"fa fa-caret-right\"></i> <a href=\"{0}{1}\">{2}</a></span>",
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));
}
if(!this.IsRoot)
if (!this.IsRoot)
{
fragments.Add("</li>");
}
@@ -167,13 +201,83 @@ namespace Docnet
}


private NavigationLevel CreateGeneratedLevel(string path)
{
var root = new NavigationLevel(_rootDirectory)
{
ParentContainer = this
};

foreach (var mdFile in Directory.GetFiles(path, "*.md", SearchOption.TopDirectoryOnly))
{
var name = FindTitleInMdFile(mdFile);
if (string.IsNullOrWhiteSpace(name))
{
continue;
}

var item = new SimpleNavigationElement
{
Name = name,
Value = Utils.MakeRelativePath(mdFile, _rootDirectory),
ParentContainer = root
};

root.Value.Add(item);
}

foreach (var directory in Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly))
{
var subDirectoryNavigationElement = CreateGeneratedLevel(directory);
subDirectoryNavigationElement.Name = new DirectoryInfo(directory).Name;
subDirectoryNavigationElement.ParentContainer = root;

root.Value.Add(subDirectoryNavigationElement);
}
return root;
}


private string FindTitleInMdFile(string path)
{
var title = string.Empty;

using (var fileStream = File.OpenRead(path))
{
using (var streamReader = new StreamReader(fileStream))
{
var line = string.Empty;
while (string.IsNullOrWhiteSpace(line))
{
line = streamReader.ReadLine();
if (!string.IsNullOrWhiteSpace(line))
{
line = line.Trim();
while (line.StartsWith("#"))
{
line = line.Substring(1).Trim();
}
if (!string.IsNullOrWhiteSpace(line))
{
title = line;
break;
}
}
}
}
}

return title;
}


#region Properties
public override string TargetURL
{
get
{
var defaultElement = this.IndexElement;
if(defaultElement == null)
if (defaultElement == null)
{
return string.Empty;
}
@@ -187,20 +291,20 @@ namespace Docnet
get
{
var toReturn = this.Value.FirstOrDefault(e => e.IsIndexElement) as SimpleNavigationElement;
if(toReturn == null)
if (toReturn == null)
{
// no index element, add an artificial one.
var path = string.Empty;
if(this.ParentContainer != null)
if (this.ParentContainer != null)
{
path = Path.GetDirectoryName(this.ParentContainer.TargetURL);
}
var nameToUse = this.Name.Replace(".", "").Replace('/', '_').Replace("\\", "_").Replace(":", "").Replace(" ", "");
if(string.IsNullOrWhiteSpace(nameToUse))
if (string.IsNullOrWhiteSpace(nameToUse))
{
return null;
}
toReturn = new SimpleNavigationElement() {ParentContainer = this, Value = string.Format("{0}{1}.md", path, nameToUse), Name = this.Name, IsIndexElement = true};
toReturn = new SimpleNavigationElement() { ParentContainer = this, Value = string.Format("{0}{1}.md", path, nameToUse), Name = this.Name, IsIndexElement = true };
this.Value.Add(toReturn);
}

@@ -216,7 +320,8 @@ namespace Docnet
{
// never an index
get { return false; }
set {
set
{
// nop;
}
}


Loading…
Cancel
Save