Example #1
0
        /// <summary>
        /// Populates a <see cref="ListViewItem"/> with information from <paramref name="file"/>.
        /// </summary>
        /// <param name="lvi">The listview item to fill with data.</param>
        /// <param name="file">The file information.</param>
        private void PopulateListViewItem(ListViewItem lvi, OutputFileInfo file)
        {
            lvi.Tag = file;

            if (this.ProjectOutput != null && this.ProjectOutput.ProjectInfo.IsExcluded(file.SourceFile))
            {
                lvi.ForeColor  = Color.Gray;
                lvi.ImageIndex = this.GetFileImageIndex("$excluded");
            }
            else
            {
                lvi.ForeColor  = this.listView1.ForeColor;
                lvi.ImageIndex = this.GetFileImageIndex(file.Extension);
            }

            int i = 0;

            this.PopulateListViewItem(lvi, i++, file.Name);
            this.PopulateListViewItem(lvi, i++, file.Modified.ToString("yyyy-MM-dd HH:mm:ss"));
            this.PopulateListViewItem(lvi, i++, file.Type);
            this.PopulateListViewItem(lvi, i++, file.Size.ToHumanReadableSize());
            this.PopulateListViewItem(lvi, i++, !string.IsNullOrEmpty(file.SourceFile) ? System.IO.Path.GetFileName(file.SourceFile) : string.Empty);
            this.PopulateListViewItem(lvi, i++, file.SourceFile);
            this.PopulateListViewItem(lvi, i++);
        }
Example #2
0
        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);
        }
Example #3
0
        /// <summary>
        /// Creates a new <see cref="ListViewItem"/> and populates it with file information.
        /// </summary>
        /// <param name="file">The file data to populate the listview item with.</param>
        private void PopulateListViewItem(OutputFileInfo file)
        {
            var lvi = new ListViewItem();

            this.PopulateListViewItem(lvi, file);

            this.listView1.Items.Add(lvi);
        }
        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);
        }
        /// <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);
        }
Example #6
0
        /// <summary>
        /// Populates a <see cref="ListViewItem"/> with information from <paramref name="file"/>.
        /// </summary>
        /// <param name="lvi">The listview item to fill with data.</param>
        /// <param name="file">The file information.</param>
        private void PopulateListViewItem(ListViewItem lvi, OutputFileInfo file)
        {
            lvi.Tag = file;

            if (this.ProjectOutput != null && this.ProjectOutput.ProjectInfo.IsExcluded(file.SourceFile))
            {
                lvi.ForeColor = Color.Gray;
                lvi.ImageIndex = this.GetFileImageIndex("$excluded");
            }
            else
            {
                lvi.ForeColor = this.listView1.ForeColor;
                lvi.ImageIndex = this.GetFileImageIndex(file.Extension);
            }

            int i = 0;
            this.PopulateListViewItem(lvi, i++, file.Name);
            this.PopulateListViewItem(lvi, i++, file.Modified.ToString("yyyy-MM-dd HH:mm:ss"));
            this.PopulateListViewItem(lvi, i++, file.Type);
            this.PopulateListViewItem(lvi, i++, file.Size.ToHumanReadableSize());
            this.PopulateListViewItem(lvi, i++, !string.IsNullOrEmpty(file.SourceFile) ? System.IO.Path.GetFileName(file.SourceFile) : string.Empty);
            this.PopulateListViewItem(lvi, i++, file.SourceFile);
            this.PopulateListViewItem(lvi, i++);
        }
Example #7
0
        /// <summary>
        /// Creates a new <see cref="ListViewItem"/> and populates it with file information.
        /// </summary>
        /// <param name="file">The file data to populate the listview item with.</param>
        private void PopulateListViewItem(OutputFileInfo file)
        {
            var lvi = new ListViewItem();

            this.PopulateListViewItem(lvi, file);

            this.listView1.Items.Add(lvi);
        }
        public void TestIndexDotJsonWithNonEnglishCharacters()
        {
            var rawHtml = @"
<!DOCTYPE html>
<html>
<head>
    <meta charset=""utf-8"">
    <title>This is title in head metadata</title>
</head>
<body>
    <h1> This is Title </h1>
    <p class='data-searchable'> Hello World,
    Microsoft
    </p>
    <article>
        <h1>
            This is article title
        </h1>
        docfx can do anything...
        and it supports non-english characters like these: ãâáà êé í õôó Типы шрифтов 人物 文字
    </article>
</body>
</html>
";

            // prepares temp folder and file for testing purposes
            // ExtractSearchIndex should probably be refactored so we can test it without depending on the filesystem
            var tempTestFolder = "temp_test_folder";

            if (Directory.Exists(tempTestFolder))
            {
                Directory.Delete(tempTestFolder, true);
            }
            Directory.CreateDirectory(tempTestFolder);
            File.WriteAllText(Path.Combine(tempTestFolder, "index.html"), rawHtml, new UTF8Encoding(false));

            // prepares fake manifest object
            var outputFileInfo = new OutputFileInfo();

            outputFileInfo.RelativePath = "index.html";

            var manifestItem = new ManifestItem();

            manifestItem.OutputFiles.Add(".html", outputFileInfo);

            var manifest = new Manifest();

            manifest.Files.Add(manifestItem);

            // process the fake manifest, using tempTestFolder as the output folder
            _extractor.Process(manifest, tempTestFolder);

            var expectedIndexJSON = @"{
  ""index.html"": {
    ""href"": ""index.html"",
    ""title"": ""This is title in head metadata"",
    ""keywords"": ""Hello World, Microsoft This is article title docfx can do anything... and it supports non-english characters like these: ãâáà êé í õôó Типы шрифтов 人物 文字""
  }
}";
            var actualIndexJSON   = File.ReadAllText(Path.Combine(tempTestFolder, "index.json"), Encoding.UTF8);

            Assert.Equal(expectedIndexJSON, actualIndexJSON);
        }