diff --git a/Directory.Build.props b/Directory.Build.props index e0900528b67..cddf0d2c372 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -45,7 +45,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Docfx.Common/Docfx.Common.csproj b/src/Docfx.Common/Docfx.Common.csproj index d83fc78f609..2d8de76d877 100644 --- a/src/Docfx.Common/Docfx.Common.csproj +++ b/src/Docfx.Common/Docfx.Common.csproj @@ -8,6 +8,11 @@ + + + + + diff --git a/src/Docfx.Common/EntityMergers/MergePlacement.cs b/src/Docfx.Common/EntityMergers/MergePlacement.cs new file mode 100644 index 00000000000..44c92c44ad7 --- /dev/null +++ b/src/Docfx.Common/EntityMergers/MergePlacement.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements.\r +// The .NET Foundation licenses this file to you under the MIT license. + + +namespace Docfx.Common.EntityMergers; + + +/// +/// The placement for a merge. +/// +internal enum MergePlacement +{ + + /// + /// The placement is not specified. + /// + None, + + /// + /// The override must be placed after the original content. + /// + After, + + /// + /// The override must be placed before the original content. + /// + Before, + + /// + /// The override must replace the original content. + /// + Replace +} diff --git a/src/Docfx.Common/EntityMergers/ReflectionEntityMerger.cs b/src/Docfx.Common/EntityMergers/ReflectionEntityMerger.cs index 3854d88600b..505d307c55b 100644 --- a/src/Docfx.Common/EntityMergers/ReflectionEntityMerger.cs +++ b/src/Docfx.Common/EntityMergers/ReflectionEntityMerger.cs @@ -80,8 +80,55 @@ public void Merge(ref object source, object overrides, IMergeContext context) { return; } + + + // Gets the placement of the override + var placement = MergePlacement.None; + + { + if (overrides is IItemWithMetadata ovr + && ovr.Metadata.TryGetValue("placement", out var placementValue)) + { + placement = + placementValue switch + { + "after" => MergePlacement.After, + "before" => MergePlacement.Before, + "replace" => MergePlacement.Replace, + _ => MergePlacement.None + }; + } + } + + foreach (var prop in Props) { + + // Placement specified in the override file + if (placement != MergePlacement.None + && prop.Prop.Name is "Remarks" or "Summary") + { + var o = prop.Prop.GetValue(overrides); + + if (o is null) + continue; + + var s = prop.Prop.GetValue(source); + + s = placement switch + { + MergePlacement.After => $"{s}{o}", + MergePlacement.Before => $"{o}{s}", + MergePlacement.Replace => o.ToString() + }; + + prop.Prop.SetValue(source, s); + + continue; + } + + + // Placement specified in the property switch (prop.Option) { case MergeOption.Merge: diff --git a/src/Docfx.Common/IItemWithMetadata.cs b/src/Docfx.Common/IItemWithMetadata.cs new file mode 100644 index 00000000000..8968a3552a8 --- /dev/null +++ b/src/Docfx.Common/IItemWithMetadata.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements.\r +// The .NET Foundation licenses this file to you under the MIT license. + + +namespace Docfx.Common; + + +/// +/// An item that contains metadate +/// +internal interface IItemWithMetadata +{ + + /// + /// Gets the metadata. + /// + /// The metadata. + Dictionary Metadata { get; } + +} diff --git a/src/Docfx.Dotnet/ManagedReference/Models/ItemViewModel.cs b/src/Docfx.Dotnet/ManagedReference/Models/ItemViewModel.cs index dac1880ed40..e740c12868a 100644 --- a/src/Docfx.Dotnet/ManagedReference/Models/ItemViewModel.cs +++ b/src/Docfx.Dotnet/ManagedReference/Models/ItemViewModel.cs @@ -13,7 +13,7 @@ namespace Docfx.DataContracts.ManagedReference; -public class ItemViewModel : IOverwriteDocumentViewModel +public class ItemViewModel : IOverwriteDocumentViewModel, IItemWithMetadata { [YamlMember(Alias = Constants.PropertyName.Uid)] [JsonProperty(Constants.PropertyName.Uid)]