mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-12-16 01:41:14 +08:00
332 lines
13 KiB
C#
332 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.Encodings.Web;
|
|
using System.Text.Json;
|
|
using AntDesign.Docs.Build.CLI.Extensions;
|
|
using AntDesign.Docs.Build.CLI.Utils;
|
|
using Microsoft.Extensions.CommandLineUtils;
|
|
|
|
namespace AntDesign.Docs.Build.CLI.Command
|
|
{
|
|
public class GenerateMenuJsonCommand : IAppCommand
|
|
|
|
{
|
|
public string Name => "menu2json";
|
|
|
|
private static readonly Dictionary<string, int> _sortMap = new Dictionary<string, int>()
|
|
{
|
|
["Docs"] = -2,
|
|
["文档"] = -2,
|
|
["Overview"] = -1,
|
|
["组件总览"] = -1,
|
|
["General"] = 0,
|
|
["通用"] = 0,
|
|
["Layout"] = 1,
|
|
["布局"] = 1,
|
|
["Navigation"] = 2,
|
|
["导航"] = 2,
|
|
["Data Entry"] = 3,
|
|
["数据录入"] = 3,
|
|
["Data Display"] = 4,
|
|
["数据展示"] = 4,
|
|
["Feedback"] = 5,
|
|
["反馈"] = 5,
|
|
["Localization"] = 6,
|
|
["Other"] = 7,
|
|
["其他"] = 7,
|
|
["Charts"] = 8,
|
|
["图表"] = 8
|
|
};
|
|
|
|
private static readonly Dictionary<string, string> _demoCategoryMap = new Dictionary<string, string>()
|
|
{
|
|
["Components"] = "组件",
|
|
["Charts"] = "图表"
|
|
};
|
|
|
|
public void Execute(CommandLineApplication command)
|
|
{
|
|
command.Description = "Generate json file for menu";
|
|
command.HelpOption();
|
|
|
|
CommandArgument demoDirArgument = command.Argument(
|
|
"demoDir", "[Required] The directory of docs files.");
|
|
|
|
CommandArgument docsDirArgument = command.Argument(
|
|
"docsDir", "[Required] The directory of docs files.");
|
|
|
|
CommandArgument outputArgument = command.Argument(
|
|
"output", "[Required] The directory where the json file to output");
|
|
|
|
command.OnExecute(() =>
|
|
{
|
|
string demoDir = demoDirArgument.Value;
|
|
string docsDir = docsDirArgument.Value;
|
|
string output = outputArgument.Value;
|
|
|
|
if (string.IsNullOrEmpty(demoDir) || !Directory.Exists(demoDir))
|
|
{
|
|
Console.WriteLine("Invalid demoDir.");
|
|
return 1;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(docsDir) || !Directory.Exists(docsDir))
|
|
{
|
|
Console.WriteLine("Invalid docsDir.");
|
|
return 1;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(output))
|
|
{
|
|
output = "./";
|
|
}
|
|
|
|
string demoDirectory = Path.Combine(Directory.GetCurrentDirectory(), demoDir);
|
|
string docsDirectory = Path.Combine(Directory.GetCurrentDirectory(), docsDir);
|
|
|
|
GenerateFiles(demoDirectory, docsDirectory, output);
|
|
|
|
return 0;
|
|
});
|
|
}
|
|
|
|
private void GenerateFiles(string demoDirectory, string docsDirectory, string output)
|
|
{
|
|
DirectoryInfo demoDirectoryInfo = new DirectoryInfo(demoDirectory);
|
|
if (!demoDirectoryInfo.Exists)
|
|
{
|
|
Console.WriteLine("{0} is not a directory", demoDirectory);
|
|
return;
|
|
}
|
|
|
|
DirectoryInfo docsDirectoryInfo = new DirectoryInfo(docsDirectory);
|
|
if (!docsDirectoryInfo.Exists)
|
|
{
|
|
Console.WriteLine("{0} is not a directory", docsDirectory);
|
|
return;
|
|
}
|
|
|
|
var jsonOptions = new JsonSerializerOptions()
|
|
{
|
|
WriteIndented = true,
|
|
IgnoreNullValues = true,
|
|
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
|
};
|
|
|
|
IList<Dictionary<string, DemoMenuItem>> docsMenuList = GetSubMenuList(docsDirectoryInfo, true).ToList();
|
|
|
|
Dictionary<string, Dictionary<string, IEnumerable<DemoMenuItem>>> categoryDemoMenuList = new Dictionary<string, Dictionary<string, IEnumerable<DemoMenuItem>>>();
|
|
List<Dictionary<string, DemoMenuItem>> allComponentMenuList = new List<Dictionary<string, DemoMenuItem>>();
|
|
|
|
foreach (var subDemoDirectory in demoDirectoryInfo.GetFileSystemInfos())
|
|
{
|
|
var category = subDemoDirectory.Name;
|
|
|
|
IList<Dictionary<string, DemoMenuItem>> componentMenuList = GetSubMenuList(subDemoDirectory as DirectoryInfo, false).ToList();
|
|
|
|
allComponentMenuList.AddRange(componentMenuList);
|
|
|
|
var componentMenuI18N = componentMenuList
|
|
.SelectMany(x => x)
|
|
.GroupBy(x => x.Key)
|
|
.ToDictionary(x => x.Key, x => x.Select(o => o.Value));
|
|
|
|
foreach (var component in componentMenuI18N)
|
|
{
|
|
if (!categoryDemoMenuList.ContainsKey(component.Key))
|
|
{
|
|
categoryDemoMenuList[component.Key] = new Dictionary<string, IEnumerable<DemoMenuItem>>();
|
|
}
|
|
categoryDemoMenuList[component.Key].Add(category, component.Value);
|
|
}
|
|
}
|
|
|
|
var docsMenuI18N = docsMenuList
|
|
.SelectMany(x => x)
|
|
.GroupBy(x => x.Key)
|
|
.ToDictionary(x => x.Key, x => x.Select(x => x.Value));
|
|
|
|
foreach (var lang in new[] { "zh-CN", "en-US" })
|
|
{
|
|
List<DemoMenuItem> menu = new List<DemoMenuItem>();
|
|
|
|
var children = docsMenuI18N[lang].OrderBy(x => x.Order).ToArray();
|
|
|
|
menu.Add(new DemoMenuItem()
|
|
{
|
|
Order = 0,
|
|
Title = lang == "zh-CN" ? "文档" : "Docs",
|
|
Type = "subMenu",
|
|
Url = "docs",
|
|
Children = children
|
|
});
|
|
|
|
var categoryComponent = categoryDemoMenuList[lang];
|
|
|
|
foreach (var component in categoryComponent)
|
|
{
|
|
menu.Add(new DemoMenuItem()
|
|
{
|
|
Order = Array.IndexOf(_demoCategoryMap.Select(x => x.Key).ToArray(), component.Key) + 1,
|
|
Title = lang == "zh-CN" ? _demoCategoryMap[component.Key] : component.Key,
|
|
Type = "subMenu",
|
|
Url = component.Key.ToLowerInvariant(),
|
|
Children = component.Value.OrderBy(x => x.Order).ToArray()
|
|
});
|
|
}
|
|
|
|
var json = JsonSerializer.Serialize(menu, jsonOptions);
|
|
|
|
var configFileDirectory = Path.Combine(Directory.GetCurrentDirectory(), output);
|
|
if (!Directory.Exists(configFileDirectory))
|
|
{
|
|
Directory.CreateDirectory(configFileDirectory);
|
|
}
|
|
|
|
var configFilePath = Path.Combine(configFileDirectory, $"menu.{lang}.json");
|
|
|
|
if (File.Exists(configFilePath))
|
|
{
|
|
File.Delete(configFilePath);
|
|
}
|
|
|
|
File.WriteAllText(configFilePath, json);
|
|
|
|
var componentI18N = allComponentMenuList
|
|
.SelectMany(x => x)
|
|
.GroupBy(x => x.Key)
|
|
.ToDictionary(x => x.Key, x => x.Select(o => o.Value));
|
|
|
|
var demos = componentI18N[lang];
|
|
|
|
var demosPath = Path.Combine(configFileDirectory, $"demos.{lang}.json");
|
|
|
|
if (File.Exists(demosPath))
|
|
{
|
|
File.Delete(demosPath);
|
|
}
|
|
|
|
json = JsonSerializer.Serialize(demos, jsonOptions);
|
|
File.WriteAllText(demosPath, json);
|
|
|
|
var docs = docsMenuI18N[lang];
|
|
var docsPath = Path.Combine(configFileDirectory, $"docs.{lang}.json");
|
|
|
|
if (File.Exists(docsPath))
|
|
{
|
|
File.Delete(docsPath);
|
|
}
|
|
|
|
json = JsonSerializer.Serialize(docs, jsonOptions);
|
|
File.WriteAllText(docsPath, json);
|
|
}
|
|
}
|
|
|
|
private IEnumerable<Dictionary<string, DemoMenuItem>> GetSubMenuList(DirectoryInfo directory, bool isDocs)
|
|
{
|
|
if (isDocs)
|
|
{
|
|
foreach (FileSystemInfo docItem in directory.GetFileSystemInfos())
|
|
{
|
|
if (docItem.Extension != ".md")
|
|
continue;
|
|
|
|
string[] segments = docItem.Name.Split('.');
|
|
if (segments.Length != 3)
|
|
continue;
|
|
|
|
string language = segments[1];
|
|
string content = File.ReadAllText(docItem.FullName);
|
|
Dictionary<string, string> docData = DocParser.ParseHeader(content);
|
|
|
|
yield return (new Dictionary<string, DemoMenuItem>()
|
|
{
|
|
[language] = new DemoMenuItem()
|
|
{
|
|
Order = int.TryParse(docData["order"], out var order) ? order : 0,
|
|
Title = docData["title"],
|
|
Url = $"docs/{segments[0]}",
|
|
Type = "menuItem"
|
|
}
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var componentI18N = GetComponentI18N(directory);
|
|
foreach (IGrouping<string, KeyValuePair<string, DemoComponent>> group in componentI18N.GroupBy(x => x.Value.Type))
|
|
{
|
|
Dictionary<string, DemoMenuItem> menu = new Dictionary<string, DemoMenuItem>();
|
|
|
|
foreach (IGrouping<string, KeyValuePair<string, DemoComponent>> component in group.GroupBy(x => x.Key))
|
|
{
|
|
menu.Add(component.Key, new DemoMenuItem()
|
|
{
|
|
Order = _sortMap[group.Key],
|
|
Title = group.Key,
|
|
Type = "itemGroup",
|
|
Children = group.Select(x => new DemoMenuItem()
|
|
{
|
|
Title = x.Value.Title,
|
|
SubTitle = x.Value.SubTitle,
|
|
Url = $"{directory.Name.ToLowerInvariant()}/{x.Value.Title.ToLower()}",
|
|
Type = "menuItem",
|
|
Cover = x.Value.Cover,
|
|
})
|
|
.OrderBy(x => x.Title, new MenuComparer())
|
|
.ToArray(),
|
|
});
|
|
}
|
|
|
|
yield return menu;
|
|
}
|
|
}
|
|
}
|
|
|
|
private IEnumerable<KeyValuePair<string, DemoComponent>> GetComponentI18N(DirectoryInfo directory)
|
|
{
|
|
IList<Dictionary<string, DemoComponent>> componentList = null;
|
|
|
|
foreach (FileSystemInfo component in directory.GetFileSystemInfos())
|
|
{
|
|
if (!(component is DirectoryInfo componentDirectory))
|
|
continue;
|
|
|
|
Dictionary<string, DemoComponent> componentDic = new Dictionary<string, DemoComponent>();
|
|
|
|
FileSystemInfo docDir = componentDirectory.GetFileSystemInfos("doc")[0];
|
|
|
|
foreach (FileSystemInfo docItem in (docDir as DirectoryInfo).GetFileSystemInfos())
|
|
{
|
|
string language = docItem.Name.Replace("index.", "").Replace(docItem.Extension, "");
|
|
string content = File.ReadAllText(docItem.FullName);
|
|
(Dictionary<string, string> Meta, string Desc, string ApiDoc) docData = DocParser.ParseDemoDoc(content);
|
|
|
|
componentDic.Add(language, new DemoComponent()
|
|
{
|
|
Title = docData.Meta["title"],
|
|
SubTitle = docData.Meta.TryGetValue("subtitle", out var subtitle) ? subtitle : null,
|
|
Type = docData.Meta["type"],
|
|
Desc = docData.Desc,
|
|
ApiDoc = docData.ApiDoc,
|
|
Cover = docData.Meta.TryGetValue("cover", out var cover) ? cover : null,
|
|
});
|
|
}
|
|
|
|
componentList ??= new List<Dictionary<string, DemoComponent>>();
|
|
componentList.Add(componentDic);
|
|
}
|
|
|
|
if (componentList == null)
|
|
return Enumerable.Empty<KeyValuePair<string, DemoComponent>>();
|
|
|
|
IEnumerable<KeyValuePair<string, DemoComponent>> componentI18N = componentList
|
|
.SelectMany(x => x).OrderBy(x => _sortMap[x.Value.Type]);
|
|
|
|
return componentI18N;
|
|
}
|
|
}
|
|
}
|