in src/tooling/docs-assembler/Navigation/GlobalNavigationFile.cs [55:143]
public static ImmutableHashSet<Uri> GetAllPathPrefixes(AssembleContext context) =>
GetSourceUris("toc", context);
public static ImmutableHashSet<Uri> GetPhantomPrefixes(AssembleContext context) =>
GetSourceUris("phantoms", context);
private static ImmutableHashSet<Uri> GetSourceUris(string key, AssembleContext context)
{
var reader = new YamlStreamReader(context.NavigationPath, context.Collector);
var set = new HashSet<Uri>();
foreach (var entry in reader.Read())
{
if (entry.Key == key && key == "toc")
ReadPathPrefixes(reader, entry.Entry, set);
if (entry.Key == key && key == "phantoms")
ReadPhantomTocs(reader, entry.Entry, set);
}
return set.ToImmutableHashSet();
static void ReadPhantomTocs(YamlStreamReader reader, KeyValuePair<YamlNode, YamlNode> entry, HashSet<Uri> hashSet)
{
if (entry.Value is not YamlSequenceNode sequence)
{
reader.EmitWarning($"'{entry.Value}' is not an array");
return;
}
foreach (var tocEntry in sequence.Children.OfType<YamlMappingNode>())
{
foreach (var child in tocEntry.Children)
{
var key = ((YamlScalarNode)child.Key).Value;
switch (key)
{
case "toc":
var source = reader.ReadString(child);
if (source != null && !source.Contains("://"))
source = ContentSourceMoniker.CreateString(NarrativeRepository.RepositoryName, source);
if (source is not null)
_ = hashSet.Add(new Uri(source));
break;
}
}
}
}
static void ReadPathPrefixes(YamlStreamReader reader, KeyValuePair<YamlNode, YamlNode> entry, HashSet<Uri> hashSet, string? parent = null)
{
if (entry.Key is not YamlScalarNode { Value: not null } scalarKey)
{
reader.EmitWarning($"key '{entry.Key}' is not string");
return;
}
if (entry.Value is not YamlSequenceNode sequence)
{
reader.EmitWarning($"'{scalarKey.Value}' is not an array");
return;
}
foreach (var tocEntry in sequence.Children.OfType<YamlMappingNode>())
{
var source = ReadToc(reader, tocEntry, ref parent, out var pathPrefix, out var sourceUri);
if (sourceUri is not null && pathPrefix is not null)
{
var pathUri = new Uri($"{sourceUri.Scheme}://{pathPrefix.TrimEnd('/')}/");
if (!hashSet.Add(pathUri))
reader.EmitError($"Duplicate path prefix in the same repository: {pathUri}", tocEntry);
}
foreach (var child in tocEntry.Children)
{
var key = ((YamlScalarNode)child.Key).Value;
switch (key)
{
case "children":
if (source is null && pathPrefix is null)
{
reader.EmitWarning("toc entry has no toc or path_prefix defined");
continue;
}
ReadPathPrefixes(reader, child, hashSet);
break;
}
}
}
}
}