mirror of https://github.com/abpframework/abp.git
28 changed files with 492 additions and 397 deletions
@ -0,0 +1,13 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Docs.Documents |
|||
{ |
|||
public class DocumentParameterDto |
|||
{ |
|||
public string Name { get; set; } |
|||
|
|||
public string DisplayName { get; set; } |
|||
|
|||
public Dictionary<string, string> Values { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Docs.Documents |
|||
{ |
|||
public class DocumentParametersDto |
|||
{ |
|||
public List<DocumentParameterDto> Parameters {get;set;} |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Docs.Language; |
|||
using Volo.Docs.Projects; |
|||
|
|||
namespace Volo.Docs.Documents |
|||
{ |
|||
public class GetParametersDocumentInput |
|||
{ |
|||
public Guid ProjectId { get; set; } |
|||
|
|||
[StringLength(ProjectConsts.MaxVersionNameLength)] |
|||
public string Version { get; set; } |
|||
|
|||
[Required] |
|||
[StringLength(LanguageConsts.MaxLanguageCodeLength)] |
|||
public string LanguageCode { get; set; } |
|||
} |
|||
} |
|||
@ -1,97 +0,0 @@ |
|||
using Microsoft.Extensions.Logging; |
|||
using Microsoft.Extensions.Logging.Abstractions; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public class DocumentSectionFinder : IDocumentSectionFinder |
|||
{ |
|||
public ILogger<DocumentSectionFinder> Logger { get; set; } |
|||
|
|||
public DocumentSectionFinder() |
|||
{ |
|||
Logger = NullLogger<DocumentSectionFinder>.Instance; |
|||
} |
|||
|
|||
public DocumentSectionDictionary Find(string document) |
|||
{ |
|||
try |
|||
{ |
|||
return FindNextSections(document, new DocumentSectionDictionary()); |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
Logger.LogWarning( |
|||
$"Incorrect usage of \"{DocumentSectionConsts.SectionOpenerPrefix}" +
|
|||
$"KEY{DocumentSectionConsts.SectionOpenerKeyValueSeparator}" + |
|||
$"VALUE{DocumentSectionConsts.SectionOpenerPostfix}..{DocumentSectionConsts.SectionCloser}\" syntax.");
|
|||
return new DocumentSectionDictionary(); |
|||
} |
|||
} |
|||
|
|||
private DocumentSectionDictionary FindNextSections(string targetPartOfDocument, DocumentSectionDictionary sections) |
|||
{ |
|||
var startOfSection = targetPartOfDocument.IndexOf(DocumentSectionConsts.SectionOpenerPrefix, StringComparison.InvariantCulture); |
|||
|
|||
if (startOfSection < 0) |
|||
{ |
|||
return sections; |
|||
} |
|||
|
|||
var endOfSectionOpener = targetPartOfDocument.Substring(startOfSection).IndexOf(DocumentSectionConsts.SectionOpenerPostfix, StringComparison.InvariantCulture); |
|||
|
|||
var keysValues = targetPartOfDocument.Substring(startOfSection) |
|||
[DocumentSectionConsts.SectionOpenerPrefix.Length..endOfSectionOpener]; |
|||
|
|||
sections = ParseAndAddContidionToSections(keysValues, sections); |
|||
|
|||
return FindNextSections(targetPartOfDocument.Substring(endOfSectionOpener), sections); |
|||
} |
|||
|
|||
private DocumentSectionDictionary ParseAndAddContidionToSections(string keysValues, DocumentSectionDictionary sections) |
|||
{ |
|||
if (keysValues.Contains(DocumentSectionConsts.SectionOpenerAndCondition, StringComparison.InvariantCulture)) |
|||
{ |
|||
var keysValuesSplitted = keysValues.Split(DocumentSectionConsts.SectionOpenerAndCondition); |
|||
foreach (var keyValue in keysValuesSplitted) |
|||
{ |
|||
sections = AddContidionToSections(keyValue, sections); |
|||
} |
|||
} |
|||
else if (keysValues.Contains(DocumentSectionConsts.SectionOpenerOrCondition, StringComparison.InvariantCulture)) |
|||
{ |
|||
var keysValuesSplitted = keysValues.Split(DocumentSectionConsts.SectionOpenerOrCondition); |
|||
foreach (var keyValue in keysValuesSplitted) |
|||
{ |
|||
sections = AddContidionToSections(keyValue, sections); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
sections = AddContidionToSections(keysValues, sections); |
|||
} |
|||
|
|||
return sections; |
|||
} |
|||
|
|||
private DocumentSectionDictionary AddContidionToSections(string keyValueWithSeparator, DocumentSectionDictionary sections) |
|||
{ |
|||
var keyValue = keyValueWithSeparator.Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator); |
|||
|
|||
var key = keyValue[0]; |
|||
var value = keyValue[1]; |
|||
|
|||
if (sections.ContainsKey(key)) |
|||
{ |
|||
sections[key].AddIfNotContains(value); |
|||
} |
|||
else |
|||
{ |
|||
sections.Add(key, new List<string>() { value }); |
|||
} |
|||
|
|||
return sections; |
|||
} |
|||
} |
|||
} |
|||
@ -1,51 +0,0 @@ |
|||
using System; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public class DocumentSectionHtmlReplacer : IDocumentSectionHtmlReplacer |
|||
{ |
|||
public string Replace(string document) |
|||
{ |
|||
while (document.Contains(DocumentSectionConsts.SectionOpenerPrefix)) |
|||
{ |
|||
var sectionIndex = document.IndexOf(DocumentSectionConsts.SectionOpenerPrefix, StringComparison.InvariantCulture); |
|||
|
|||
var sectionCloserIndex = document.Substring(sectionIndex + DocumentSectionConsts.SectionOpenerPrefix.Length) |
|||
.IndexOf(DocumentSectionConsts.SectionOpenerPostfix, StringComparison.InvariantCulture); |
|||
|
|||
var keysValues = document.Substring(sectionIndex + DocumentSectionConsts.SectionOpenerPrefix.Length) |
|||
[0..sectionCloserIndex]; |
|||
|
|||
var andOperation = keysValues.Contains(DocumentSectionConsts.SectionOpenerAndCondition, StringComparison.InvariantCulture); |
|||
var orOperation = keysValues.Contains(DocumentSectionConsts.SectionOpenerOrCondition, StringComparison.InvariantCulture); |
|||
|
|||
var splitterChar = andOperation ? DocumentSectionConsts.SectionOpenerAndCondition : DocumentSectionConsts.SectionOpenerOrCondition; |
|||
|
|||
string[] keysValuesSplitted = keysValues.Split(splitterChar); |
|||
|
|||
var keys = new string[keysValuesSplitted.Length]; |
|||
var values = new string[keysValuesSplitted.Length]; |
|||
|
|||
for (int i = 0; i < keysValuesSplitted.Length; i++) |
|||
{ |
|||
keys[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[0]; |
|||
values[i] = keysValuesSplitted[i].Split(DocumentSectionConsts.SectionOpenerKeyValueSeparator)[1]; |
|||
} |
|||
|
|||
var div = $"<span class=\"doc-section\" data-keys=\"" + |
|||
$"{string.Join(splitterChar, keys)}" + |
|||
$"\" data-values=\"" + |
|||
$"{string.Join(splitterChar, values)}" + |
|||
$"\">";
|
|||
|
|||
document = document.Remove(sectionIndex, sectionCloserIndex + DocumentSectionConsts.SectionOpenerPrefix.Length +1); |
|||
|
|||
document = document.Insert(sectionIndex, div); |
|||
} |
|||
|
|||
document = document.Replace(DocumentSectionConsts.SectionCloser, "</span>"); |
|||
|
|||
return document; |
|||
} |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public interface IDocumentSectionFinder: ITransientDependency |
|||
{ |
|||
public DocumentSectionDictionary Find(string document); |
|||
} |
|||
} |
|||
@ -1,9 +0,0 @@ |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public interface IDocumentSectionHtmlReplacer : ITransientDependency |
|||
{ |
|||
public string Replace(string document); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public interface IDocumentSectionRenderer: ITransientDependency |
|||
{ |
|||
Task<string> Render(string doucment, DocumentRenderParameters parameters); |
|||
|
|||
Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document); |
|||
} |
|||
} |
|||
@ -0,0 +1,115 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Newtonsoft.Json; |
|||
using Scriban; |
|||
|
|||
namespace Volo.Docs.HtmlConverting |
|||
{ |
|||
public class ScribanDocumentSectionRenderer : IDocumentSectionRenderer |
|||
{ |
|||
public async Task<string> Render(string document, DocumentRenderParameters parameters = null) |
|||
{ |
|||
Template scribanTemplate; |
|||
if (parameters == null) |
|||
{ |
|||
scribanTemplate = Template.Parse(document); |
|||
return scribanTemplate.Render(); |
|||
} |
|||
|
|||
var p2 = new Dictionary<string, string>(); |
|||
|
|||
foreach (var item in parameters) |
|||
{ |
|||
p2.Add(item.Key, item.Value); |
|||
} |
|||
|
|||
scribanTemplate = Template.Parse(document); |
|||
var result = scribanTemplate.Render(p2); |
|||
|
|||
try |
|||
{ |
|||
return await RemoveOptionsJson(result); |
|||
} |
|||
catch (Exception) |
|||
{ |
|||
return scribanTemplate.Render(); |
|||
} |
|||
} |
|||
|
|||
public async Task<Dictionary<string, List<string>>> GetAvailableParametersAsync(string document) |
|||
{ |
|||
try |
|||
{ |
|||
var jsonOpener = "````json"; |
|||
var jsonCloser = "````"; |
|||
var docs_param = "//[doc-params]"; |
|||
|
|||
if (!document.Contains(jsonOpener)) |
|||
{ |
|||
return new Dictionary<string, List<string>>(); |
|||
} |
|||
|
|||
var searchedIndex = 0; |
|||
while (searchedIndex < document.Length) |
|||
{ |
|||
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(jsonOpener) + jsonOpener.Length + searchedIndex; |
|||
var JsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser) + jsonBeginningIndex; |
|||
var insideJsonSection = document[jsonBeginningIndex..JsonEndingIndex]; |
|||
|
|||
if (insideJsonSection.IndexOf(docs_param) < 0) |
|||
{ |
|||
searchedIndex = JsonEndingIndex + jsonCloser.Length; |
|||
continue; |
|||
} |
|||
|
|||
var pureJson = insideJsonSection.Replace(docs_param, "").Trim(); |
|||
|
|||
return JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(pureJson); |
|||
} |
|||
|
|||
return new Dictionary<string, List<string>>(); |
|||
} |
|||
catch (Exception e) |
|||
{ |
|||
//log
|
|||
return new Dictionary<string, List<string>>(); |
|||
} |
|||
} |
|||
|
|||
private async Task<string> RemoveOptionsJson(string document) |
|||
{ |
|||
var jsonOpener = "````json"; |
|||
var jsonCloser = "````"; |
|||
var docs_param = "//[doc-params]"; |
|||
|
|||
var searchedIndex = 0; |
|||
while (searchedIndex < document.Length) |
|||
{ |
|||
var jsonBeginningIndex = document.Substring(searchedIndex).IndexOf(jsonOpener) + jsonOpener.Length + searchedIndex; |
|||
|
|||
if (jsonBeginningIndex < 0) |
|||
{ |
|||
return document; |
|||
} |
|||
|
|||
var JsonEndingIndex = document.Substring(jsonBeginningIndex).IndexOf(jsonCloser) + jsonBeginningIndex; |
|||
var insideJsonSection = document[jsonBeginningIndex..JsonEndingIndex]; |
|||
|
|||
if (insideJsonSection.IndexOf(docs_param) < 0) |
|||
{ |
|||
searchedIndex = JsonEndingIndex + jsonCloser.Length; |
|||
continue; |
|||
} |
|||
|
|||
return document.Remove( |
|||
jsonBeginningIndex - jsonOpener.Length, (JsonEndingIndex + jsonCloser.Length) - (jsonBeginningIndex - jsonOpener.Length) |
|||
); |
|||
|
|||
} |
|||
|
|||
return document; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue