private ManifestItem UpdateItem(ManifestItem item, string sourceRelativePath) { var result = item.Clone(); result.IsIncremental = true; result.SourceRelativePath = sourceRelativePath; Parallel.ForEach( from ofi in result.OutputFiles.Values where ofi.LinkToPath != null where ofi.LinkToPath.Length > IncrementalContext.LastBaseDir.Length where ofi.LinkToPath.StartsWith(IncrementalContext.LastBaseDir) where (ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '\\' || ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '/') select ofi, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, ofi => { IncrementalUtility.RetryIO(() => { var path = Path.Combine(IncrementalContext.BaseDir, IncrementalUtility.GetRandomEntry(IncrementalContext.BaseDir)); File.Copy(Environment.ExpandEnvironmentVariables(ofi.LinkToPath), Environment.ExpandEnvironmentVariables(path)); ofi.LinkToPath = path; }); }); return(result); }
public override void Handle(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile) { foreach (var node in document.DocumentNode.Descendants()) { if (!node.HasAttributes) { continue; } foreach (var attr in node.ChildAttributes("sourceFile")) { attr.Remove(); } foreach (var attr in node.ChildAttributes("sourceStartLineNumber")) { attr.Remove(); } foreach (var attr in node.ChildAttributes("sourceEndLineNumber")) { attr.Remove(); } foreach (var attr in node.ChildAttributes("data-raw-source")) { attr.Remove(); } } }
private ManifestItem UpdateItem(ManifestItem item, string sourceRelativePath) { var result = item.Clone(); result.IsIncremental = true; result.SourceRelativePath = sourceRelativePath; // Copy when current base dir is not last base dir if (!FilePathComparerWithEnvironmentVariable.OSPlatformSensitiveRelativePathComparer.Equals( IncrementalContext.BaseDir, IncrementalContext.LastBaseDir)) { foreach (var ofi in result.OutputFiles.Values) { if (ofi.LinkToPath != null && ofi.LinkToPath.Length > IncrementalContext.LastBaseDir.Length && ofi.LinkToPath.StartsWith(IncrementalContext.LastBaseDir, StringComparison.Ordinal) && (ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '\\' || ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '/')) { IncrementalUtility.RetryIO(() => { var path = Path.Combine(IncrementalContext.BaseDir, IncrementalUtility.GetRandomEntry(IncrementalContext.BaseDir)); File.Copy(Environment.ExpandEnvironmentVariables(ofi.LinkToPath), Environment.ExpandEnvironmentVariables(path)); ofi.LinkToPath = path; }); } } } return(result); }
protected override void HandleCore(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile) { _fileMapping[outputFile] = inputFile; // RFC 3986: relative-ref = relative-part [ "?" query ] [ "#" fragment ] _linksWithBookmark[outputFile] = (from node in GetNodesWithAttribute(document, "href") let nocheck = node.GetAttributeValue("nocheck", null) where !"bookmark".Equals(nocheck, StringComparison.OrdinalIgnoreCase) let link = node.GetAttributeValue("href", null) let bookmark = UriUtility.GetFragment(link).TrimStart('#') let decodedLink = RelativePath.TryParse(HttpUtility.UrlDecode(UriUtility.GetPath(link))) where !string.IsNullOrEmpty(bookmark) && !WhiteList.Contains(bookmark) where decodedLink != null select new LinkItem { Title = node.InnerText, Href = TransformPath(outputFile, decodedLink), Bookmark = bookmark, SourceFragment = WebUtility.HtmlDecode(node.GetAttributeValue("data-raw-source", null)), SourceFile = WebUtility.HtmlDecode(node.GetAttributeValue("sourceFile", null)), SourceLineNumber = node.GetAttributeValue("sourceStartLineNumber", 0), TargetLineNumber = node.Line }).ToList(); var anchors = GetNodeAttribute(document, "id").Concat(GetNodeAttribute(document, "name")); _registeredBookmarks[outputFile] = new HashSet <string>(anchors); }
public Manifest Process(Manifest manifest, string outputFolder) { if (outputFolder == null) { throw new ArgumentNullException("Base directory can not be null"); } var indexData = new SortedDictionary <string, SearchIndexItem>(); var indexDataFilePath = Path.Combine(outputFolder, IndexFileName); var htmlFiles = (from item in manifest.Files ?? Enumerable.Empty <ManifestItem>() from output in item.OutputFiles where item.DocumentType != "Toc" && output.Key.Equals(".html", StringComparison.OrdinalIgnoreCase) select output.Value.RelativePath).ToList(); if (htmlFiles.Count == 0) { return(manifest); } Logger.LogInfo($"Extracting index data from {htmlFiles.Count} html files"); foreach (var relativePath in htmlFiles) { var filePath = Path.Combine(outputFolder, relativePath); var html = new HtmlDocument(); Logger.LogDiagnostic($"Extracting index data from {filePath}"); if (EnvironmentContext.FileAbstractLayer.Exists(filePath)) { try { using var stream = EnvironmentContext.FileAbstractLayer.OpenRead(filePath); html.Load(stream, Encoding.UTF8); } catch (Exception ex) { Logger.LogWarning($"Warning: Can't load content from {filePath}: {ex.Message}"); continue; } var indexItem = ExtractItem(html, relativePath); if (indexItem != null) { indexData[relativePath] = indexItem; } } } JsonUtility.Serialize(indexDataFilePath, indexData, Formatting.Indented); // add index.json to manifest as resource file var manifestItem = new ManifestItem { DocumentType = "Resource", }; manifestItem.OutputFiles.Add("resource", new OutputFileInfo { RelativePath = PathUtility.MakeRelativePath(outputFolder, indexDataFilePath), }); manifest.Files?.Add(manifestItem); return(manifest); }
public ManifestItemWithContext(ManifestItem item, FileModel model, IDocumentProcessor processor, TemplateBundle bundle) { Item = item; FileModel = model; Processor = processor; TemplateBundle = bundle; }
public void Handle(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile) { string phase = GetType().Name; using (new LoggerPhaseScope(phase)) { HandleCore(document, manifestItem, inputFile, outputFile); } }
public SystemMetadata Generate(ManifestItem item) { var attrs = new SystemMetadata { Language = Constants.DefaultLanguage, }; string key = GetFileKey(item.Key); var file = (RelativePath)item.ModelFile; attrs.RelativePathToRoot = (RelativePath.Empty).MakeRelativeTo(file); attrs.PathFromRoot = file.RemoveWorkingFolder(); // 1. Root Toc is always in the top directory of output folder var rootToc = _toc.FirstOrDefault(); if (rootToc != null) { var rootTocPath = rootToc.RemoveWorkingFolder(); if (rootTocPath.SubdirectoryCount == 0) { attrs.RootTocPath = rootTocPath; attrs.RootTocRelativePath = attrs.RootTocPath == null ? null : rootTocPath.MakeRelativeTo(file); Logger.LogVerbose($"Root TOC file {rootTocPath} is found."); } else { Logger.LogVerbose($"Root TOC file from output folder is not found, the toppest TOC file is {rootTocPath}"); } } // 2. The algorithm of toc current article belongs to: // a. If toc can be found in TocMap, return that toc // b. Elsewise, get the nearest toc, **nearest** means nearest toc in **OUTPUT** folder var parentTocFiles = _context.GetTocFileKeySet(key)?.Select(s => _context.GetFilePath(s)); var parentToc = GetNearestToc(parentTocFiles); if (parentToc == null) { parentToc = GetDefaultToc(key); } if (parentToc != null) { var parentTocPath = parentToc.RemoveWorkingFolder(); attrs.TocPath = parentTocPath; attrs.TocRelativePath = attrs.TocPath == null ? null : parentTocPath.MakeRelativeTo(file); Logger.LogVerbose($"TOC file {parentTocPath} is found for {item.LocalPathFromRepoRoot}."); } else { Logger.LogVerbose($"TOC file for {item.LocalPathFromRepoRoot} is not found."); } return(attrs); }
private IEnumerable <TransformModelOptions> GetOptionsForEachTemplate(ManifestItem item, IDocumentBuildContext context) { if (item == null) { yield break; } foreach (var template in Templates) { if (template.ContainsGetOptions) { yield return(template.GetOptions(item.Model.Content)); } } }
protected override void HandleCore(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile) { foreach (var node in document.DocumentNode.Descendants()) { if (!node.HasAttributes) { continue; } foreach (var remove in DebugInfoAttributes) { foreach (var attr in node.ChildAttributes(remove)) { attr.Remove(); } } } }
private ManifestItem UpdateItem(ManifestItem item, string sourceRelativePath) { var result = item.Clone(); result.IsIncremental = true; result.SourceRelativePath = sourceRelativePath; foreach (var ofi in result.OutputFiles.Values) { if (ofi.LinkToPath != null && ofi.LinkToPath.Length > IncrementalContext.LastBaseDir.Length && ofi.LinkToPath.StartsWith(IncrementalContext.LastBaseDir) && (ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '\\' || ofi.LinkToPath[IncrementalContext.LastBaseDir.Length] == '/')) { IncrementalUtility.RetryIO(() => { var path = Path.Combine(IncrementalContext.BaseDir, IncrementalUtility.GetRandomEntry(IncrementalContext.BaseDir)); File.Copy(Environment.ExpandEnvironmentVariables(ofi.LinkToPath), Environment.ExpandEnvironmentVariables(path)); ofi.LinkToPath = path; }); } } return(result); }
protected abstract void HandleCore(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile);
private void TransformDocument(string result, string extension, IDocumentBuildContext context, string destFilePath, ManifestItem manifestItem, out List <XRefDetails> unresolvedXRefs) { Task <byte[]> hashTask; unresolvedXRefs = new List <XRefDetails>(); using (var stream = EnvironmentContext.FileAbstractLayer.Create(destFilePath).WithMd5Hash(out hashTask)) using (var sw = new StreamWriter(stream)) { if (extension.Equals(".html", StringComparison.OrdinalIgnoreCase)) { TransformHtml(context, result, manifestItem.SourceRelativePath, destFilePath, sw, out unresolvedXRefs); } else { sw.Write(result); } } var ofi = new OutputFileInfo { RelativePath = destFilePath, LinkToPath = GetLinkToPath(destFilePath), Hash = Convert.ToBase64String(hashTask.Result) }; manifestItem.OutputFiles.Add(extension, ofi); }
/// <summary> /// Must guarantee thread safety /// </summary> /// <param name="item"></param> /// <returns></returns> internal ManifestItem Transform(InternalManifestItem item) { if (item.Model == null || item.Model.Content == null) { throw new ArgumentNullException("Content for item.Model should not be null!"); } var model = ConvertObjectToDictionary(item.Model.Content); model = AppendGlobalMetadata(model); if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportRawModel)) { ExportModel(model, item.FileWithoutExtension, _settings.RawModelExportSettings); } var manifestItem = new ManifestItem { DocumentType = item.DocumentType, SourceRelativePath = item.LocalPathFromRoot, OutputFiles = new Dictionary <string, OutputFileInfo>(), Metadata = item.Metadata, }; var outputDirectory = _settings.OutputFolder ?? Environment.CurrentDirectory; // 1. process resource if (item.ResourceFile != null) { // Resource file has already been processed in its plugin manifestItem.OutputFiles.Add("resource", new OutputFileInfo { RelativePath = item.ResourceFile, LinkToPath = null, Hash = null }); } // 2. process model var templateBundle = _templateCollection[item.DocumentType]; if (templateBundle == null) { return(manifestItem); } HashSet <string> missingUids = new HashSet <string>(); // Must convert to JObject first as we leverage JsonProperty as the property name for the model foreach (var template in templateBundle.Templates) { if (!template.ContainsTemplateRenderer) { continue; } var extension = template.Extension; string outputFile = item.FileWithoutExtension + extension; string outputPath = Path.Combine(outputDirectory, outputFile); var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } object viewModel = null; try { viewModel = template.TransformModel(model); } catch (Exception e) { // save raw model for further investigation: var exportSettings = ApplyTemplateSettings.RawModelExportSettingsForDebug; var rawModelPath = ExportModel(model, item.FileWithoutExtension, exportSettings); var message = $"Error transforming model \"{rawModelPath}\" generated from \"{item.LocalPathFromRoot}\" using \"{template.ScriptName}\": {e.Message}"; Logger.LogError(message); throw new DocumentException(message, e); } string result; try { result = template.Transform(viewModel); } catch (Exception e) { // save view model for further investigation: var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug; var viewModelPath = ExportModel(viewModel, outputFile, exportSettings); var message = $"Error applying template \"{template.Name}\" to view model \"{viewModelPath}\" generated from \"{item.LocalPathFromRoot}\": {e.Message}"; Logger.LogError(message); throw new DocumentException(message, e); } if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportViewModel)) { ExportModel(viewModel, outputFile, _settings.ViewModelExportSettings); } if (_settings.Options.HasFlag(ApplyTemplateOptions.TransformDocument)) { if (string.IsNullOrWhiteSpace(result)) { // TODO: WHAT to do if is transformed to empty string? STILL creat empty file? var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug; var viewModelPath = ExportModel(viewModel, outputFile, exportSettings); Logger.LogWarning($"Model \"{viewModelPath}\" is transformed to empty string with template \"{template.Name}\""); File.WriteAllText(outputPath, string.Empty); } else { TransformDocument(result, extension, _context, outputPath, outputFile, missingUids, manifestItem); Logger.LogDiagnostic($"Transformed model \"{item.LocalPathFromRoot}\" to \"{outputPath}\"."); } } } if (missingUids.Count > 0) { var uids = string.Join(", ", missingUids.Select(s => $"\"{s}\"")); Logger.LogWarning($"Unable to resolve cross-reference {uids}"); } return(manifestItem); }
private static void TransformDocument(string result, string extension, IDocumentBuildContext context, string outputPath, string relativeOutputPath, HashSet <string> missingUids, ManifestItem manifestItem) { var subDirectory = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(subDirectory) && !Directory.Exists(subDirectory)) { Directory.CreateDirectory(subDirectory); } Task <byte[]> hashTask; using (var stream = File.Create(outputPath).WithMd5Hash(out hashTask)) using (var sw = new StreamWriter(stream)) { if (extension.Equals(".html", StringComparison.OrdinalIgnoreCase)) { try { TranformHtml(context, result, relativeOutputPath, sw); } catch (AggregateException e) { e.Handle(s => { var xrefExcetpion = s as CrossReferenceNotResolvedException; if (xrefExcetpion != null) { missingUids.Add(xrefExcetpion.UidRawText); return(true); } else { return(false); } }); } } else { sw.Write(result); } } manifestItem.OutputFiles.Add(extension, new OutputFileInfo { RelativePath = relativeOutputPath, LinkToPath = null, Hash = Convert.ToBase64String(hashTask.Result) }); }
private TemplateManifestItem TransformItem(ManifestItem item, IDocumentBuildContext context, ApplyTemplateSettings settings, SystemMetadataGenerator systemAttributeGenerator) { if (settings.Options.HasFlag(ApplyTemplateOptions.ExportRawModel)) { ExportModel(item.Model.Content, item.ModelFile, settings.RawModelExportSettings); } if (item.Model == null || item.Model.Content == null) { throw new ArgumentNullException("Content for item.Model should not be null!"); } var manifestItem = new TemplateManifestItem { DocumentType = item.DocumentType, OriginalFile = item.LocalPathFromRepoRoot, OutputFiles = new Dictionary <string, string>() }; var outputDirectory = settings.OutputFolder ?? Environment.CurrentDirectory; if (!IsEmpty) { HashSet <string> missingUids = new HashSet <string>(); // Must convert to JObject first as we leverage JsonProperty as the property name for the model var model = ConvertToObjectHelper.ConvertStrongTypeToJObject(item.Model.Content); var templates = Templates[item.DocumentType]; // 1. process model if (templates != null) { var systemAttrs = systemAttributeGenerator.Generate(item); foreach (var template in templates) { var extension = template.Extension; string outputFile = Path.ChangeExtension(item.ModelFile, extension); string outputPath = Path.Combine(outputDirectory, outputFile); var dir = Path.GetDirectoryName(outputPath); if (!string.IsNullOrEmpty(dir)) { Directory.CreateDirectory(dir); } object viewModel = null; try { viewModel = template.TransformModel(model, systemAttrs, _global); } catch (Exception e) { // save raw model for further investigation: var exportSettings = ApplyTemplateSettings.RawModelExportSettingsForDebug; var rawModelPath = ExportModel(model, item.ModelFile, exportSettings); throw new DocumentException($"Error transforming model \"{rawModelPath}\" generated from \"{item.LocalPathFromRepoRoot}\" using \"{template.ScriptName}\": {e.Message}"); } string result; try { result = template.Transform(viewModel); } catch (Exception e) { // save view model for further investigation: var exportSettings = ApplyTemplateSettings.ViewModelExportSettingsForDebug; var viewModelPath = ExportModel(viewModel, outputFile, exportSettings); throw new DocumentException($"Error applying template \"{template.Name}\" to view model \"{viewModelPath}\" generated from \"{item.LocalPathFromRepoRoot}\": {e.Message}"); } if (settings.Options.HasFlag(ApplyTemplateOptions.ExportViewModel)) { ExportModel(viewModel, outputFile, settings.ViewModelExportSettings); } if (settings.Options.HasFlag(ApplyTemplateOptions.TransformDocument)) { if (string.IsNullOrWhiteSpace(result)) { // TODO: WHAT to do if is transformed to empty string? STILL creat empty file? Logger.LogWarning($"Model \"{item.ModelFile}\" is transformed to empty string with template \"{template.Name}\""); File.WriteAllText(outputPath, string.Empty); } else { TransformDocument(result, extension, context, outputPath, item.ModelFile, missingUids); Logger.Log(LogLevel.Verbose, $"Transformed model \"{item.LocalPathFromRepoRoot}\" to \"{outputPath}\"."); } manifestItem.OutputFiles.Add(extension, outputFile); } } } if (missingUids.Count > 0) { var uids = string.Join(", ", missingUids.Select(s => $"\"{s}\"")); Logger.LogWarning($"Unable to resolve cross-reference {uids} for \"{manifestItem.OriginalFile.ToDisplayPath()}\""); } } // 2. process resource if (item.ResourceFile != null) { // Resource file has already been processed in its plugin manifestItem.OutputFiles.Add("resource", item.ResourceFile); } return(manifestItem); }
public TransformModelOptions GetOptions(ManifestItem item, IDocumentBuildContext context) { return(MergeOptions(GetOptionsForEachTemplate(item, context))); }
private void TransformDocument(string result, string extension, IDocumentBuildContext context, string destFilePath, HashSet <string> missingUids, ManifestItem manifestItem) { Task <byte[]> hashTask; using (var stream = EnvironmentContext.FileAbstractLayer.Create(destFilePath).WithMd5Hash(out hashTask)) using (var sw = new StreamWriter(stream)) { if (extension.Equals(".html", StringComparison.OrdinalIgnoreCase)) { try { TransformHtml(context, result, manifestItem.SourceRelativePath, destFilePath, sw); } catch (AggregateException e) { e.Handle(s => { var xrefExcetpion = s as CrossReferenceNotResolvedException; if (xrefExcetpion != null) { missingUids.Add(xrefExcetpion.UidRawText); return(true); } else { return(false); } }); } } else { sw.Write(result); } } var ofi = new OutputFileInfo { RelativePath = destFilePath, LinkToPath = GetLinkToPath(destFilePath), Hash = Convert.ToBase64String(hashTask.Result) }; manifestItem.OutputFiles.Add(extension, ofi); }
private static FileModel Load( IDocumentProcessor processor, ImmutableDictionary <string, object> metadata, FileMetadata fileMetadata, FileAndType file, bool canProcessorIncremental, IDictionary <string, XRefSpec> xrefSpecMap, IEnumerable <ManifestItem> manifestItems, DependencyGraph dg, DocumentBuildContext context) { using (new LoggerFileScope(file.File)) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Loading..."); if (canProcessorIncremental) { ChangeKindWithDependency ck; string fileKey = ((RelativePath)file.File).GetPathFromWorkingFolder().ToString(); if (context.ChangeDict.TryGetValue(fileKey, out ck)) { if (ck == ChangeKindWithDependency.Deleted) { return(null); } if (ck == ChangeKindWithDependency.None) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Check incremental..."); if (((ISupportIncrementalBuild)processor).CanIncrementalBuild(file) && processor.BuildSteps.Cast <ISupportIncrementalBuild>().All(step => step.CanIncrementalBuild(file))) { Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Skip build by incremental."); // restore filemap context.FileMap[fileKey] = ((RelativePath)file.File).GetPathFromWorkingFolder(); // restore xrefspec var specs = xrefSpecMap?.Values?.Where(spec => spec.Href == fileKey); if (specs != null) { foreach (var spec in specs) { context.XRefSpecMap[spec.Uid] = spec; } } // restore manifestitem ManifestItem item = manifestItems?.SingleOrDefault(i => i.SourceRelativePath == file.File); if (item != null) { context.ManifestItems.Add(item); } // restore dependency graph if (dg.HasDependency(fileKey)) { context.DependencyGraph.ReportDependency(fileKey, dg.GetDirectDependency(fileKey)); } return(null); } Logger.LogDiagnostic($"Processor {processor.Name}, File {file.FullPath}: Incremental not available."); } } } var path = Path.Combine(file.BaseDir, file.File); metadata = ApplyFileMetadata(path, metadata, fileMetadata); try { return(processor.Load(file, metadata)); } catch (Exception) { Logger.LogError($"Unable to load file: {file.File} via processor: {processor.Name}."); throw; } } }
public abstract void Handle(HtmlDocument document, ManifestItem manifestItem, string inputFile, string outputFile);
/// <summary> /// Must guarantee thread safety /// </summary> /// <param name="item"></param> /// <returns></returns> internal ManifestItem Transform(InternalManifestItem item) { if (item.Model == null || item.Model.Content == null) { throw new ArgumentNullException("Content for item.Model should not be null!"); } var model = ConvertObjectToDictionary(item.Model.Content); model = AppendGlobalMetadata(model); if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportRawModel)) { ExportModel(model, item.FileWithoutExtension, _settings.RawModelExportSettings); } var manifestItem = new ManifestItem { DocumentType = item.DocumentType, SourceRelativePath = item.LocalPathFromRoot, Metadata = item.Metadata, Version = _context.VersionName, }; var outputDirectory = _settings.OutputFolder ?? Directory.GetCurrentDirectory(); // 1. process resource if (item.ResourceFile != null) { // Resource file has already been processed in its plugin var ofi = new OutputFileInfo { RelativePath = item.ResourceFile, LinkToPath = GetLinkToPath(item.ResourceFile), }; manifestItem.OutputFiles.Add("resource", ofi); } // 2. process model var templateBundle = _templateCollection[item.DocumentType]; if (templateBundle == null) { return(manifestItem); } HashSet <string> missingUids = new HashSet <string>(); // Must convert to JObject first as we leverage JsonProperty as the property name for the model foreach (var template in templateBundle.Templates) { if (!template.ContainsTemplateRenderer) { continue; } try { var extension = template.Extension; string outputFile = item.FileWithoutExtension + extension; object viewModel = null; try { viewModel = template.TransformModel(model); } catch (Exception e) { string message; if (_settings.DebugMode) { // save raw model for further investigation: var rawModelPath = ExportModel(model, item.FileWithoutExtension, _settings.RawModelExportSettingsForDebug); message = $"Error transforming model \"{rawModelPath}\" generated from \"{item.LocalPathFromRoot}\" using \"{template.ScriptName}\". {e.Message}"; } else { message = $"Error transforming model generated from \"{item.LocalPathFromRoot}\" using \"{template.ScriptName}\". To get the detailed raw model, please run docfx with debug mode --debug. {e.Message} "; } Logger.LogError(message); throw new DocumentException(message, e); } string result; try { result = template.Transform(viewModel); } catch (Exception e) { string message; if (_settings.DebugMode) { // save view model for further investigation: var viewModelPath = ExportModel(viewModel, outputFile, _settings.ViewModelExportSettingsForDebug); message = $"Error applying template \"{template.Name}\" to view model \"{viewModelPath}\" generated from \"{item.LocalPathFromRoot}\". {e.Message}"; } else { message = $"Error applying template \"{template.Name}\" generated from \"{item.LocalPathFromRoot}\". To get the detailed view model, please run docfx with debug mode --debug. {e.Message}"; } Logger.LogError(message); throw new DocumentException(message, e); } if (_settings.Options.HasFlag(ApplyTemplateOptions.ExportViewModel)) { ExportModel(viewModel, outputFile, _settings.ViewModelExportSettings); } if (_settings.Options.HasFlag(ApplyTemplateOptions.TransformDocument)) { if (string.IsNullOrWhiteSpace(result)) { string message; if (_settings.DebugMode) { var viewModelPath = ExportModel(viewModel, outputFile, _settings.ViewModelExportSettingsForDebug); message = $"Model \"{viewModelPath}\" is transformed to empty string with template \"{template.Name}\""; } else { message = $"Model is transformed to empty string with template \"{template.Name}\". To get the detailed view model, please run docfx with debug mode --debug"; } Logger.LogWarning(message); } TransformDocument(result ?? string.Empty, extension, _context, outputFile, missingUids, manifestItem); Logger.LogDiagnostic($"Transformed model \"{item.LocalPathFromRoot}\" to \"{outputFile}\"."); } } catch (PathTooLongException e) { var message = $"Error processing {item.LocalPathFromRoot}: {e.Message}"; throw new PathTooLongException(message, e); } } if (missingUids.Count > 0) { var uids = string.Join(", ", missingUids.Select(s => $"\"{s}\"")); Logger.LogWarning($"Invalid cross reference {uids}.", null, item.LocalPathFromRoot); } return(manifestItem); }
public ManifestItemWithContext(ManifestItem item, FileModel model, IDocumentProcessor processor) { Item = item; FileModel = model; Processor = processor; }