UDNParser.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
  2. #pragma once
  3. #include "CoreMinimal.h"
  4. #include "Misc/Attribute.h"
  5. #include "Input/Reply.h"
  6. #include "Widgets/SWidget.h"
  7. #include "IDocumentationPage.h"
  8. #include "Types/SlateStructs.h"
  9. #include "IDocumentation.h"
  10. #include "Brushes/SlateDynamicImageBrush.h"
  11. #include "DocumentationDefines.h"
  12. namespace EXT_DOC_NAMESPACE
  13. {
  14. /** Stores all the metadata that a UDN page can have */
  15. struct FUDNPageMetadata
  16. {
  17. FUDNPageMetadata()
  18. : Availability()
  19. , Title()
  20. , Crumbs()
  21. , Description()
  22. , ExcerptNames()
  23. {}
  24. FString Availability;
  25. FText Title;
  26. FText Crumbs;
  27. FText Description;
  28. TSet< FString > ExcerptNames;
  29. };
  30. /** Represents a single UDN Markdown token */
  31. namespace EUDNToken
  32. {
  33. enum Type
  34. {
  35. Content,
  36. Pound,
  37. OpenBracket,
  38. CloseBracket,
  39. OpenParenthesis,
  40. CloseParenthesis,
  41. Numbering,
  42. Bang,
  43. Excerpt,
  44. Variable,
  45. Colon,
  46. Slash,
  47. Dash,
  48. MetadataAvailability,
  49. MetadataTitle,
  50. MetadataCrumbs,
  51. MetadataDescription,
  52. Percentage,
  53. Asterisk
  54. };
  55. }
  56. /** A token, which can also have content */
  57. struct FUDNToken
  58. {
  59. FUDNToken(EUDNToken::Type InTokenType, const FString& InContent = FString())
  60. : TokenType(InTokenType)
  61. , Content(InContent) {}
  62. EUDNToken::Type TokenType;
  63. FString Content;
  64. };
  65. /** A UDN line, which, since we parse line by line, will correspond to a single slate widget */
  66. struct FUDNLine
  67. {
  68. public:
  69. /** The type of line this is */
  70. enum Type
  71. {
  72. Ignored,
  73. VariableReference,
  74. Whitespace,
  75. Content,
  76. NumberedContent,
  77. Header1,
  78. Header2,
  79. ExcerptOpen,
  80. ExcerptClose,
  81. Image,
  82. Link,
  83. ImageLink,
  84. HorizontalRule,
  85. MetadataAvailability,
  86. MetadataTitle,
  87. MetadataCrumbs,
  88. MetadataDescription,
  89. Variable,
  90. VariableOpen,
  91. VariableClose,
  92. BoldContent
  93. };
  94. Type ContentType;
  95. /** Optional string/path content that is used by this line */
  96. TArray<FString> AdditionalContent;
  97. FUDNLine()
  98. : ContentType(FUDNLine::Ignored) {}
  99. FUDNLine(FUDNLine::Type InLineType, const FString& InStringContent = FString(), const FString& InPathContent = FString())
  100. : ContentType(InLineType) {}
  101. };
  102. /**
  103. * A Parser for UDN Files, turning them into Slate widgets
  104. * It only provides a very small subset of what UDN files have to offer:
  105. * - Text
  106. * - Headers
  107. * - Numbering
  108. * - Horizontal Rules
  109. * - Images (can't be inline)
  110. * - Hyperlinks (can't be inline)
  111. * - Image Hyperlinks
  112. * - Excerpts (currently, it only parses what's in excerpts)
  113. * Currently, it parses pages into an array based on the excerpts
  114. */
  115. class FExtUDNParser : public TSharedFromThis< FExtUDNParser >
  116. {
  117. public:
  118. static TSharedRef< FExtUDNParser > Create( const TSharedPtr< FParserConfiguration >& ParserConfig, const FDocumentationStyle& Style );
  119. public:
  120. ~FExtUDNParser();
  121. /**
  122. * Parses the UDN page specified by the Path, returning true if successful,
  123. * and giving back a list of widgets created by the parsing, split
  124. * based on the beginning and ending of excerpts
  125. */
  126. bool Parse(const FString& Link, TArray< FExcerpt >& OutContentSections, FUDNPageMetadata& OutMetadata);
  127. bool GetExcerptContent( const FString& Link, FExcerpt& Excerpt, bool bInSimpleText = false );
  128. /** Allows a TAttribute to be set to control excerpt wrapat values from outside the parser. */
  129. void SetWrapAt( TAttribute<float> InWrapAt );
  130. private:
  131. bool bSimpleText = false;
  132. /** UI Callbacks for the widgets */
  133. FReply OnImageLinkClicked(FString Payload);
  134. /** Adds the content text source to the scrollbox */
  135. void AddContentToExcerpt(TSharedPtr<SVerticalBox> Box, const FString& ContentSource, FExcerpt& Excerpt);
  136. /** Gets the dynamic brush for the given filename */
  137. TSharedPtr<FSlateDynamicImageBrush> GetDynamicBrushFromImagePath(FString Filename);
  138. /** Helper function which appends a content section to the scrollbox */
  139. void AppendExcerpt(TSharedPtr<SVerticalBox> Box, TSharedRef<SWidget> Content);
  140. /** Turns a series of symbols (or a single symbol) back to string format */
  141. FString ConvertSymbolIntoAString(const FUDNToken& Token);
  142. FString ConvertSymbolsIntoAString(const TArray<FUDNToken>& TokenList, int32 StartingAfterIndex = 0);
  143. /** Given a line, converts it into UDN tokens, returning true if successful */
  144. bool ParseLineIntoSymbols(int32 LineNumber, const FString& Line, TArray<FUDNToken>& SymbolList);
  145. /** Given a line, convert it into an FUDNLine which can be used by Slate */
  146. FUDNLine ParseLineIntoUDNContent(int32 LineNumber, const FString& Line);
  147. bool LoadLink( const FString& Link, TArray<FString>& ContentLines );
  148. TSharedRef< SWidget > GenerateExcerptContent( const FString& Link, FExcerpt& Excerpt, const TArray<FString>& ContentLines, int32 StartingLineIndex );
  149. bool ParseSymbols( const FString& Link, const TArray<FString>& ContentLines, const FString& FullPath, TArray<FExcerpt>& OutExcerpts, FUDNPageMetadata& OutMetadata );
  150. void HandleHyperlinkNavigate( FString AdditionalContent );
  151. void NavigateToLink( FString AdditionalContent );
  152. private:
  153. /**
  154. * Parses a code link embedded in the doc.
  155. * Allows us to specify files in code to link to in one of 2 ways. In both cases the last 2 parameters are line and column.
  156. * [Project based link](CODELINK:Private/[PROJECT]File.cpp, 29, 5)
  157. * This will attempt to parse the active solution name and replace instances of [PROJECT] within this so
  158. * (CODELINK:Private/[PROJECT]Ball.cpp, 29, 5) will in a project called marble will equate to
  159. * <UE4ROOT>Marble/Source/Marble/Private/MarbleBall.cpp
  160. * [Explicit link](CODELINK:Templates/TP_Rolling/Source/TP_Rolling/Private/TP_Rolling.cpp will equate to
  161. * <UE4ROOT>Templates/TP_Rolling/Source/TP_Rolling/Private/TP_Rolling.cpp
  162. */
  163. bool ParseCodeLink(FString &InternalLink);
  164. /**
  165. * Parses an asset link embedded in the doc.
  166. * Allows us to specify assets to either highlight or edit in the editor
  167. * (ASSETLINK:SELECT,MyCharacter)
  168. * This will highlight the MyCharacter asset in the content browser
  169. * (ASSETLINK:EDIT,MyCharacter)
  170. * This will edit the given asset in the appropriate editor window type.
  171. */
  172. bool ParseAssetLink(FString &InternalLink);
  173. FExtUDNParser( const TSharedRef< FParserConfiguration >& InConfiguration, const FDocumentationStyle& InStyle );
  174. void Initialize();
  175. /** A list of dynamic brushes we are using for the currently loaded tutorial */
  176. TArray< TSharedPtr< FSlateDynamicImageBrush > > DynamicBrushesUsed;
  177. /** Configuration details */
  178. TSharedRef< FParserConfiguration > Configuration;
  179. /** The styling we apply to generated widgets */
  180. FDocumentationStyle Style;
  181. /** A library of which tokens correspond to which series of strings */
  182. struct FTokenPair
  183. {
  184. FTokenPair(FString InParseText, EUDNToken::Type InTokenType)
  185. : ParseText(InParseText)
  186. , TokenType(InTokenType) {}
  187. FString ParseText;
  188. EUDNToken::Type TokenType;
  189. };
  190. TArray<FTokenPair> TokenLibrary;
  191. /** A library of which series of tokens correspond to which line types */
  192. struct FTokenConfiguration
  193. {
  194. FTokenConfiguration(const TArray<EUDNToken::Type>& InTokenTypes, FUDNLine::Type InOutputLineType, bool bInAcceptTrailingContent = false)
  195. : TokensAccepted(InTokenTypes)
  196. , OutputLineType(InOutputLineType)
  197. , bAcceptTrailingSymbolDumpAsContent(bInAcceptTrailingContent) {}
  198. /** Tallies the total number of content tokens in this config */
  199. int32 CalculatedExpectedContentStrings();
  200. TArray<EUDNToken::Type> TokensAccepted;
  201. FUDNLine::Type OutputLineType;
  202. bool bAcceptTrailingSymbolDumpAsContent;
  203. };
  204. TArray<FTokenConfiguration> LineLibrary;
  205. /** Documentation text wrapping control attribute */
  206. TAttribute<float> WrapAt;
  207. /** Documentation optional width control attribute */
  208. TAttribute<FOptionalSize> ContentWidth;
  209. };
  210. }