Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Added AttributeRenderer-PlugIn #1099

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===============================================================================================================
//===============================================================================================================
// System : Sandcastle Tools Standard Presentation Styles
// File : Default2022Transformation.cs
// Author : Eric Woodruff ([email protected])
Expand Down Expand Up @@ -1143,9 +1143,18 @@ private void RenderPageTitleAndLogo(XElement body)
private static void RenderNotices(TopicTransformationCore transformation)
{
var preliminary = transformation.CommentsNode.Element("preliminary");
var obsolete = transformation.ReferenceNode.AttributeOfType("T:System.ObsoleteAttribute");

List<XElement> attributeRepresentations = new List<XElement>();

foreach(var keyValuePair in ((Default2022Transformation)transformation).presentationStyle.LongAttributeRepresentations)
{
if(transformation.ReferenceNode.AttributeOfType(keyValuePair.Key) != null)
{
attributeRepresentations.Add(keyValuePair.Value);
}
}

if(preliminary != null || obsolete != null)
if(preliminary != null || attributeRepresentations.Count > 0)
{
var currentElement = transformation.CurrentElement;
var notes = new XElement("span", new XAttribute("class", "tags"));
Expand All @@ -1157,13 +1166,11 @@ private static void RenderNotices(TopicTransformationCore transformation)
if(preliminary != null)
transformation.RenderNode(preliminary);

if(obsolete != null)
foreach(XNode attributeRepresentation in attributeRepresentations)
{
notes.Add(new XElement("span",
new XAttribute("class", "tag is-danger is-medium"),
new XElement("include", new XAttribute("item", "boilerplate_obsoleteLong"))));
notes.Add(attributeRepresentation);
}

transformation.CurrentElement = currentElement;
}
}
Expand Down Expand Up @@ -1604,20 +1611,26 @@ private static void RenderApiNamespaceList(TopicTransformationCore transformatio
if(summary != null)
transformation.RenderChildElements(summaryCell, summary.Nodes());

var obsoleteAttr = e.AttributeOfType("T:System.ObsoleteAttribute");
List<XNode> attributeRepresentations = new List<XNode>();

foreach(var keyValuePair in ((Default2022Transformation)transformation).presentationStyle.ShortAttributeRepresentations)
{
if(e.AttributeOfType(keyValuePair.Key) != null)
{
attributeRepresentations.Add(keyValuePair.Value);
}
}

var prelimComment = e.Element("preliminary");

if(obsoleteAttr != null || prelimComment != null)
if(attributeRepresentations.Count > 0 || prelimComment != null)
{
if(!summaryCell.IsEmpty)
summaryCell.Add(new XElement("br"));

if(obsoleteAttr != null)
foreach(XNode attributeRepresentation in attributeRepresentations)
{
summaryCell.Add(new XElement("span",
new XAttribute("class", "tag is-danger"),
new XElement("include",
new XAttribute("item", "boilerplate_obsoleteShort"))));
summaryCell.Add(attributeRepresentation);
}

if(prelimComment != null)
Expand Down Expand Up @@ -1779,15 +1792,25 @@ private static void RenderApiEnumerationMembersList(TopicTransformationCore tran
thisTransform.RenderChildElements(summaryCell, remarks.Nodes());
}

if(e.AttributeOfType("T:System.ObsoleteAttribute") != null)
List<XNode> attributeRepresentations = new List<XNode>();

foreach(var keyValuePair in ((Default2022Transformation)transformation).presentationStyle.ShortAttributeRepresentations)
{
if(e.AttributeOfType(keyValuePair.Key) != null)
{
attributeRepresentations.Add(keyValuePair.Value);
}
}

if(attributeRepresentations.Count > 0)
{
if(!summaryCell.IsEmpty)
summaryCell.Add(new XElement("br"));

summaryCell.Add(new XElement("span",
new XAttribute("class", "tag is-danger"),
new XElement("include",
new XAttribute("item", "boilerplate_obsoleteShort"))));
foreach(XNode attributeRepresentation in attributeRepresentations)
{
summaryCell.Add(attributeRepresentation);
}
}

if(summaryCell.IsEmpty)
Expand Down Expand Up @@ -2036,20 +2059,25 @@ private static void RenderApiTypeMemberLists(TopicTransformationCore transformat
}
}

var obsoleteAttr = e.AttributeOfType("T:System.ObsoleteAttribute");
List<XNode> attributeRepresentations = new List<XNode>();

foreach(var keyValuePair in ((Default2022Transformation)transformation).presentationStyle.ShortAttributeRepresentations)
{
if(e.AttributeOfType(keyValuePair.Key) != null)
{
attributeRepresentations.Add(keyValuePair.Value);
}
}
var prelimComment = e.Element("preliminary");

if(obsoleteAttr != null || prelimComment != null)
if(attributeRepresentations.Count > 0 || prelimComment != null)
{
if(!summaryCell.IsEmpty)
summaryCell.Add(new XElement("br"));

if(obsoleteAttr != null)
foreach(XNode attributeRepresentation in attributeRepresentations)
{
summaryCell.Add(new XElement("span",
new XAttribute("class", "tag is-danger"),
new XElement("include",
new XAttribute("item", "boilerplate_obsoleteShort"))));
summaryCell.Add(attributeRepresentation);
}

if(prelimComment != null)
Expand Down
140 changes: 140 additions & 0 deletions SHFB/Source/SandcastleBuilderPlugIns/AttributeRendererPlugin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//===============================================================================================================
// System : Sandcastle Help File Builder Plug-Ins
// File : XPathReflectionFileFilterPlugIn.cs
// Author : Eric Woodruff ([email protected]) Based on code by Eyal Post
// Updated : 06/17/2021
// Note : Copyright 2008-2021, Eric Woodruff, All rights reserved
//
// This file contains a plug-in that is used to filter out unwanted information from the reflection information
// file using XPath queries.
//
// This code is published under the Microsoft Public License (Ms-PL). A copy of the license should be
// distributed with the code and can be found at the project website: https://GitHub.com/EWSoftware/SHFB. This
// notice, the author's name, and all copyright notices must remain intact in all applications, documentation,
// and source files.
//
// Date Who Comments
// ==============================================================================================================
// 10/31/2008 EFW Created the code
// 12/17/2013 EFW Updated to use MEF for the plug-ins
//===============================================================================================================

// Ignore Spelling: Eyal

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml;
using System.Xml.Linq;

using SandcastleBuilder.Utils;
using SandcastleBuilder.Utils.BuildComponent;
using SandcastleBuilder.Utils.BuildEngine;

namespace SandcastleBuilder.PlugIns
{
/// <summary>
/// This plug-in class is used to define how attributes are rendered
/// </summary>
[HelpFileBuilderPlugInExport("Attribute Renderer Plugin", RunsInPartialBuild = true,
Version = AssemblyInfo.ProductVersion, Copyright = AssemblyInfo.Copyright + "\r\nBased on code submitted by " +
"Eyal Post", Description = "This plug-in is used to define how attributes such as 'Obsolete' are rendered.")]
public sealed class AttributeRendererPlugin : IPlugIn
{
#region Private data members
//=====================================================================

private List<ExecutionPoint> executionPoints;
private BuildProcess builder;
private readonly ObservableCollection<AttributeRepresentationEntry> attributeRepresentationEntries = new ObservableCollection<AttributeRepresentationEntry>();

#endregion

#region IPlugIn implementation
//=====================================================================

/// <summary>
/// This read-only property returns a collection of execution points that define when the plug-in should
/// be invoked during the build process.
/// </summary>
public IEnumerable<ExecutionPoint> ExecutionPoints
{
get
{
if(executionPoints == null)
executionPoints = new List<ExecutionPoint>
{
new ExecutionPoint(BuildStep.ApplyDocumentModel, ExecutionBehaviors.Before)
};

return executionPoints;
}
}

/// <summary>
/// This method is used to initialize the plug-in at the start of the build process
/// </summary>
/// <param name="buildProcess">A reference to the current build process</param>
/// <param name="configuration">The configuration data that the plug-in should use to initialize itself</param>
public void Initialize(BuildProcess buildProcess, XElement configuration)
{
if(configuration == null)
throw new ArgumentNullException(nameof(configuration));

builder = buildProcess;

var metadata = (HelpFileBuilderPlugInExportAttribute)this.GetType().GetCustomAttributes(
typeof(HelpFileBuilderPlugInExportAttribute), false).First();

builder.ReportProgress("{0} Version {1}\r\n{2}", metadata.Id, metadata.Version, metadata.Copyright);

this.ReadConfiguration(configuration);

if(attributeRepresentationEntries.Count == 0)
{
throw new BuilderException("ATTR0001", "No AttributeRepresentations defined " +
"Attribute Renderer plug-in");
}
}

public void ReadConfiguration(XElement configuration)
{
foreach(var expr in configuration.Descendants("AttributeRepresentationEntry"))
AttributeRepresentationEntries.Add(AttributeRepresentationEntry.FromXml(this, expr));
}

/// <summary>
/// This method is used to execute the plug-in during the build process
/// </summary>
/// <param name="context">The current execution context</param>
public void Execute(ExecutionContext context)
{
foreach(var item in attributeRepresentationEntries)
{
if (item.HasLongRepresentation) builder.PresentationStyle.LongAttributeRepresentations[item.AttributeClassName] = item.GetLongRepresentation();
if (item.HasShortRepresentation) builder.PresentationStyle.ShortAttributeRepresentations[item.AttributeClassName] = item.GetShortRepresentation();
}
}
#endregion

#region Properties

public ObservableCollection<AttributeRepresentationEntry> AttributeRepresentationEntries => attributeRepresentationEntries;

#endregion

#region IDisposable implementation
//=====================================================================

/// <summary>
/// This implements the Dispose() interface to properly dispose of the plug-in object
/// </summary>
public void Dispose()
{
// Nothing to dispose of in this one
GC.SuppressFinalize(this);
}
#endregion
}
}
Loading