private DocumentFile LoadDocument(string file, IEnumerable<string> knownExtensions, LayoutFileCollection availableLayouts)
{
// Parse the document and update our document metadata.
//
var parser = new ParseDocumentCommand(file);
parser.Execute();
if (this.AdditionalMetadataForFiles != null)
{
var rootPath = Path.GetDirectoryName(this.DocumentsPath.TrimEnd('\\'));
var relativePath = file.Substring(rootPath.Length + 1);
foreach (var additionalMetadataConfig in this.AdditionalMetadataForFiles)
{
if (additionalMetadataConfig.Match.IsMatch(relativePath))
{
parser.Metadata.AssignFrom(file, additionalMetadataConfig.Metadata);
}
}
}
var metadataDate = parser.Date;
var partial = false;
var order = 0;
var relativeDocumentPath = Path.GetFullPath(file).Substring(this.DocumentsPath.Length);
var outputRelativePath = parser.Metadata.GetAndRemove("output", relativeDocumentPath);
// The rest of this function is about calculating the correct
// name for the file.
//
var fileName = Path.GetFileName(outputRelativePath);
var outputRelativeFolder = Path.GetDirectoryName(outputRelativePath);
var disableDateFromFileName = parser.Metadata.GetAndRemove("DisableDateFromFileName", false);
if (!disableDateFromFileName)
{
var match = DateFromFileName.Match(outputRelativePath);
if (match.Success)
{
outputRelativeFolder = match.Groups[1].Value;
// If the parser metadata didn't specify the date, use the date from the filename.
//
if (!metadataDate.HasValue)
{
var year = Convert.ToInt32(match.Groups[2].Value, 10);
var month = Convert.ToInt32(match.Groups[3].Value, 10);
var day = Convert.ToInt32(match.Groups[4].Value, 10);
var hour = match.Groups[5].Success ? Convert.ToInt32(match.Groups[5].Value, 10) : 0;
var minute = match.Groups[6].Success ? Convert.ToInt32(match.Groups[6].Value, 10) : 0;
var second = match.Groups[7].Success ? Convert.ToInt32(match.Groups[7].Value, 10) : 0;
metadataDate = new DateTime(year, month, day, hour, minute, second);
}
fileName = match.Groups[8].Value;
}
}
var disableOrderFromFileName = parser.Metadata.GetAndRemove("DisableOrderFromFileName", false);
if (!disableOrderFromFileName)
{
var match = OrderFromFileName.Match(fileName);
if (match.Success)
{
order = Convert.ToInt32(match.Groups[1].Value, 10);
fileName = fileName.Substring(match.Length);
}
}
// See if this file should be processed by any of the
// rendering engines.
//
var extensionsForRendering = new List<string>();
for (;;)
{
var extension = Path.GetExtension(fileName).TrimStart('.');
if (extension.Equals("partial", StringComparison.OrdinalIgnoreCase))
{
partial = true;
fileName = Path.GetFileNameWithoutExtension(fileName);
}
else if (knownExtensions.Contains(extension))
{
extensionsForRendering.Add(extension);
fileName = Path.GetFileNameWithoutExtension(fileName);
}
else
{
break;
}
}
var targetExtension = Path.GetExtension(fileName).TrimStart('.');
var layoutName = parser.Metadata.Get<string>("layout");
var layouts = GetLayouts(layoutName, targetExtension, file);
var parentId = String.IsNullOrEmpty(outputRelativeFolder) ? null : SanitizePath(outputRelativeFolder);
var disableInsertDateIntoPath = parser.Metadata.GetAndRemove("DisableInsertDateIntoPath", false);
if (!disableInsertDateIntoPath && metadataDate.HasValue)
{
outputRelativeFolder = Path.Combine(outputRelativeFolder, metadataDate.Value.Year.ToString(), metadataDate.Value.Month.ToString(), metadataDate.Value.Day.ToString());
}
if (!parser.Metadata.Contains("title"))
{
parser.Metadata.Add("title", Path.GetFileNameWithoutExtension(fileName));
}
// Sanitize the filename into a good URL.
//
fileName = SanitizeEntryId(fileName);
var disableSanitizePath = parser.Metadata.GetAndRemove("DisableSanitizePath", false);
if (!disableSanitizePath)
{
outputRelativeFolder = SanitizePath(outputRelativeFolder);
}
var disableCleanUrls = parser.Metadata.GetAndRemove("DisableCleanUrls", false);
if (!disableCleanUrls && !"index.html".Equals(fileName, StringComparison.OrdinalIgnoreCase) && ".html".Equals(Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase))
{
outputRelativeFolder = Path.Combine(outputRelativeFolder, Path.GetFileNameWithoutExtension(fileName)) + "\\";
fileName = null;
}
var id = String.IsNullOrEmpty(fileName) ? outputRelativeFolder : Path.Combine(outputRelativeFolder, Path.GetFileNameWithoutExtension(fileName));
var output = Path.Combine(outputRelativeFolder, fileName ?? "index.html");
var relativeUrl = this.ApplicationUrl.EnsureEndsWith("/") + Path.Combine(outputRelativeFolder, fileName ?? String.Empty).Replace('\\', '/');
// Finally create the document.
//
var documentFile = new DocumentFile(file, this.DocumentsPath, output, this.OutputRootPath, relativeUrl, this.RootUrl, this.Author, parser.Metadata, parser.Queries);
documentFile.Partial = partial;
if (metadataDate.HasValue)
{
documentFile.Date = metadataDate.Value;
}
documentFile.Id = parser.Metadata.GetAndRemove("id", id.Trim('\\'));
documentFile.ParentId = parser.Metadata.GetAndRemove("parent", parentId ?? String.Empty);
documentFile.Draft = (parser.Draft || documentFile.Date > DateTime.Now);
documentFile.Description = parser.Metadata.GetAndRemove<string>("description");
documentFile.ExtensionsForRendering = extensionsForRendering;
documentFile.AssignLayouts(layouts);
documentFile.Order = parser.Metadata.GetAndRemove("order", order);
documentFile.PaginateQuery = parser.Metadata.GetAndRemove<string>("paginate");
documentFile.SourceContent = parser.Content;
return documentFile;
}