Skip to content

Commit

Permalink
Merge pull request #20325 from abpframework/salihozkara/ImproveDocsSe…
Browse files Browse the repository at this point in the history
…ction

Support for Rendering Custom JSON Sections Starting with  "```"
  • Loading branch information
gizemmutukurt authored Aug 2, 2024
2 parents b924d00 + 697e1e2 commit 701cc9f
Showing 1 changed file with 155 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ namespace Volo.Docs.HtmlConverting
{
public class ScribanDocumentSectionRenderer : IDocumentSectionRenderer
{
private const string JsonOpener = "````json";
private const string JsonCloser = "````";
private readonly static List<DocsJsonSection> DocsJsonSections = new List<DocsJsonSection>
{
new DocsJsonSection("````json", "````"),
new DocsJsonSection("```json", "```")
};
private const string DocsParam = "//[doc-params]";
private const string DocsTemplates = "//[doc-template]";
private const string DocsNav = "//[doc-nav]";
Expand Down Expand Up @@ -59,12 +62,12 @@ public Task<DocumentNavigationsDto> GetDocumentNavigationsAsync(string documentC
{
try
{
if (!document.Contains(JsonOpener) || !document.Contains(sectionName))
if (!HasJsonSection(document) || !document.Contains(sectionName))
{
return new T();
}

var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document, sectionName);
var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection, _) = GetJsonBeginEndIndexesAndPureJson(document, sectionName);

if (jsonBeginningIndex < 0 || jsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection))
{
Expand Down Expand Up @@ -96,21 +99,21 @@ private static string RemoveOptionsJson(string document, params string[] section

try
{
if (!document.Contains(JsonOpener) || !document.Contains(sectionName))
if (!HasJsonSection(document) || !document.Contains(sectionName))
{
continue;
}

var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = GetJsonBeginEndIndexesAndPureJson(document, sectionName);
var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection, jsonSection) = GetJsonBeginEndIndexesAndPureJson(document, sectionName);

if (jsonBeginningIndex < 0 || jsonEndingIndex <= 0 || string.IsNullOrWhiteSpace(insideJsonSection))
{
continue;
}

document = document.Remove(
jsonBeginningIndex - JsonOpener.Length,
(jsonEndingIndex + JsonCloser.Length) - (jsonBeginningIndex - JsonOpener.Length)
jsonBeginningIndex - jsonSection.Opener.Length,
(jsonEndingIndex + jsonSection.Closer.Length) - (jsonBeginningIndex - jsonSection.Opener.Length)
);
}
catch (Exception)
Expand All @@ -121,122 +124,193 @@ private static string RemoveOptionsJson(string document, params string[] section

return document;
}

private static (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document, string sectionName)
private static bool HasJsonSection(string document)
{
var searchedIndex = 0;
return DocsJsonSections.Any(section => document.Contains(section.Opener) && document.Contains(section.Closer));
}

while (searchedIndex < document.Length)
private static (int, int, string, DocsJsonSection) GetJsonBeginEndIndexesAndPureJson(string document, string sectionName)
{
foreach (var section in DocsJsonSections)
{
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length + searchedIndex;

if (jsonBeginningIndex < 0)
{
return (-1, -1, "");
}

var jsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(JsonCloser, StringComparison.Ordinal) + jsonBeginningIndex;
var insideJsonSection = document[jsonBeginningIndex..jsonEndingIndex];
var (jsonBeginningIndex, jsonEndingIndex, insideJsonSection) = section.GetJsonBeginEndIndexesAndPureJson(document, sectionName);

if (insideJsonSection.IndexOf(sectionName, StringComparison.Ordinal) < 0)
if (jsonBeginningIndex >= 0 && jsonEndingIndex > 0 && !string.IsNullOrWhiteSpace(insideJsonSection))
{
searchedIndex = jsonEndingIndex + JsonCloser.Length;
continue;
return (jsonBeginningIndex, jsonEndingIndex, insideJsonSection, section);
}

return (jsonBeginningIndex, jsonEndingIndex, insideJsonSection);
}

return (-1, -1, "");
return (-1, -1, "", null);
}

public async Task<List<DocumentPartialTemplateWithValuesDto>> GetPartialTemplatesInDocumentAsync(string documentContent)
{
var templates = new List<DocumentPartialTemplateWithValuesDto>();

while (documentContent.Contains(JsonOpener))
foreach (var section in DocsJsonSections)
{
var afterJsonOpener = documentContent.Substring(
documentContent.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
);
templates.AddRange(await section.GetPartialTemplatesInDocumentAsync(documentContent));
}

var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal)
);
return templates;
}

private static string SetPartialTemplates(string document, IReadOnlyCollection<DocumentPartialTemplateContent> templates)
{
foreach (var section in DocsJsonSections)
{
document = section.SetPartialTemplates(document, templates);
}

return document;
}

private class DocsJsonSection
{
public string Opener { get; }
public string Closer { get; }

public DocsJsonSection(string opener, string closer)
{
Opener = opener;
Closer = closer;
}

documentContent = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
);
public (int, int, string) GetJsonBeginEndIndexesAndPureJson(string document, string sectionName)
{
var searchedIndex = 0;

if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
while (searchedIndex < document.Length)
{
continue;
}
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(Opener, StringComparison.Ordinal);

var json = betweenJsonOpenerAndCloser.Substring(betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) + DocsTemplates.Length);
if (jsonBeginningIndex < 0)
{
return (-1, -1, "");
}

jsonBeginningIndex += Opener.Length + searchedIndex;

if (!DocsJsonSerializerHelper.TryDeserialize<DocumentPartialTemplateWithValuesDto>(json, out var template))
{
throw new UserFriendlyException($"ERROR-20200327: Cannot validate JSON content for `AvailableParameters`!");
}
var jsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(Closer, StringComparison.Ordinal);
if (jsonEndingIndex < 0)
{
return (-1, -1, "");
}

jsonEndingIndex += jsonBeginningIndex;
var insideJsonSection = document[jsonBeginningIndex..jsonEndingIndex];

templates.Add(template);
}
if (insideJsonSection.IndexOf(sectionName, StringComparison.Ordinal) < 0)
{
searchedIndex = jsonEndingIndex + Closer.Length;
continue;
}

return await Task.FromResult(templates);
}
return (jsonBeginningIndex, jsonEndingIndex, insideJsonSection);
}

private static string SetPartialTemplates(string document, IReadOnlyCollection<DocumentPartialTemplateContent> templates)
{
var newDocument = new StringBuilder();
return (-1, -1, "");
}

while (document.Contains(JsonOpener))
public async Task<List<DocumentPartialTemplateWithValuesDto>> GetPartialTemplatesInDocumentAsync(
string documentContent)
{
var beforeJson = document.Substring(0,
document.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
);
var templates = new List<DocumentPartialTemplateWithValuesDto>();

var afterJsonOpener = document.Substring(
document.IndexOf(JsonOpener, StringComparison.Ordinal) + JsonOpener.Length
);
while (documentContent.Contains(Opener))
{
var afterJsonOpener = documentContent.Substring(
documentContent.IndexOf(Opener, StringComparison.Ordinal) + Opener.Length
);

var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal)
);
var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
afterJsonOpener.IndexOf(Closer, StringComparison.Ordinal)
);

if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
{
document = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
documentContent = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(Closer, StringComparison.Ordinal) + Closer.Length
);

newDocument.Append(beforeJson + betweenJsonOpenerAndCloser + JsonCloser);
continue;
if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
{
continue;
}

var json = betweenJsonOpenerAndCloser.Substring(
betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) +
DocsTemplates.Length);

if (!DocsJsonSerializerHelper.TryDeserialize<DocumentPartialTemplateWithValuesDto>(json,
out var template))
{
throw new UserFriendlyException(
$"ERROR-20200327: Cannot validate JSON content for `AvailableParameters`!");
}

templates.Add(template);
}

var json = betweenJsonOpenerAndCloser.Substring(
betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) + DocsTemplates.Length
);
return await Task.FromResult(templates);
}

public string SetPartialTemplates(string document,
IReadOnlyCollection<DocumentPartialTemplateContent> templates)
{
var newDocument = new StringBuilder();

if (DocsJsonSerializerHelper.TryDeserialize<DocumentPartialTemplateWithValuesDto>(json, out var documentPartialTemplateWithValuesDto))
while (document.Contains(Opener))
{
var template = templates.FirstOrDefault(t => t.Path == documentPartialTemplateWithValuesDto.Path);
var beforeJson = document.Substring(0,
document.IndexOf(Opener, StringComparison.Ordinal) + Opener.Length
);

var beforeTemplate = document.Substring(0,
document.IndexOf(JsonOpener, StringComparison.Ordinal)
var afterJsonOpener = document.Substring(
document.IndexOf(Opener, StringComparison.Ordinal) + Opener.Length
);

newDocument.Append(beforeTemplate + template?.Content + JsonCloser);
var betweenJsonOpenerAndCloser = afterJsonOpener.Substring(0,
afterJsonOpener.IndexOf(Closer, StringComparison.Ordinal)
);

if (!betweenJsonOpenerAndCloser.Contains(DocsTemplates))
{
document = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(Closer, StringComparison.Ordinal) + Closer.Length
);

newDocument.Append(beforeJson + betweenJsonOpenerAndCloser + Closer);
continue;
}

document = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(JsonCloser, StringComparison.Ordinal) + JsonCloser.Length
var json = betweenJsonOpenerAndCloser.Substring(
betweenJsonOpenerAndCloser.IndexOf(DocsTemplates, StringComparison.Ordinal) +
DocsTemplates.Length
);

if (DocsJsonSerializerHelper.TryDeserialize<DocumentPartialTemplateWithValuesDto>(json,
out var documentPartialTemplateWithValuesDto))
{
var template =
templates.FirstOrDefault(t => t.Path == documentPartialTemplateWithValuesDto.Path);

var beforeTemplate = document.Substring(0,
document.IndexOf(Opener, StringComparison.Ordinal)
);

newDocument.Append(beforeTemplate + template?.Content + Closer);

document = afterJsonOpener.Substring(
afterJsonOpener.IndexOf(Closer, StringComparison.Ordinal) + Closer.Length
);
}
}
}

newDocument.Append(document);
newDocument.Append(document);

return newDocument.ToString();
return newDocument.ToString();
}
}
}
}

0 comments on commit 701cc9f

Please sign in to comment.