| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 | // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.#pragma once#include "CoreMinimal.h"#include "Misc/Attribute.h"#include "Input/Reply.h"#include "Widgets/SWidget.h"#include "IDocumentationPage.h"#include "Types/SlateStructs.h"#include "IDocumentation.h"#include "Brushes/SlateDynamicImageBrush.h"#include "DocumentationDefines.h"namespace EXT_DOC_NAMESPACE{/** Stores all the metadata that a UDN page can have */struct FUDNPageMetadata{	FUDNPageMetadata()		: Availability()		, Title()		, Crumbs()		, Description()		, ExcerptNames() 	{}	FString Availability;	FText Title;	FText Crumbs;	FText Description;	TSet< FString > ExcerptNames;};/** Represents a single UDN Markdown token */namespace EUDNToken{	enum Type	{		Content,		Pound,		OpenBracket,		CloseBracket,		OpenParenthesis,		CloseParenthesis,		Numbering,		Bang,		Excerpt,		Variable,		Colon,		Slash,		Dash,		MetadataAvailability,		MetadataTitle,		MetadataCrumbs,		MetadataDescription,		Percentage,		Asterisk	};}/** A token, which can also have content */struct FUDNToken{	FUDNToken(EUDNToken::Type InTokenType, const FString& InContent = FString())		: TokenType(InTokenType)		, Content(InContent) {}	EUDNToken::Type TokenType;	FString Content;};/** A UDN line, which, since we parse line by line, will correspond to a single slate widget */struct FUDNLine{public:	/** The type of line this is */	enum Type	{		Ignored,		VariableReference,		Whitespace,		Content,		NumberedContent,		Header1,		Header2,		ExcerptOpen,		ExcerptClose,		Image,		Link,		ImageLink,		HorizontalRule,		MetadataAvailability,		MetadataTitle,		MetadataCrumbs,		MetadataDescription,		Variable,		VariableOpen,		VariableClose,		BoldContent	};	Type ContentType;	/** Optional string/path content that is used by this line */	TArray<FString> AdditionalContent;	FUDNLine()		: ContentType(FUDNLine::Ignored) {}	FUDNLine(FUDNLine::Type InLineType, const FString& InStringContent = FString(), const FString& InPathContent = FString())		: ContentType(InLineType) {}};/** * A Parser for UDN Files, turning them into Slate widgets * It only provides a very small subset of what UDN files have to offer: *  - Text *  - Headers *  - Numbering *  - Horizontal Rules *  - Images (can't be inline) *  - Hyperlinks (can't be inline) *  - Image Hyperlinks *  - Excerpts (currently, it only parses what's in excerpts) * Currently, it parses pages into an array based on the excerpts */class FExtUDNParser : public TSharedFromThis< FExtUDNParser >{public:	static TSharedRef< FExtUDNParser > Create( const TSharedPtr< FParserConfiguration >& ParserConfig, const FDocumentationStyle& Style );public:	~FExtUDNParser();	/**	 * Parses the UDN page specified by the Path, returning true if successful,	 * and giving back a list of widgets created by the parsing, split	 * based on the beginning and ending of excerpts	 */	bool Parse(const FString& Link, TArray< FExcerpt >& OutContentSections, FUDNPageMetadata& OutMetadata);	bool GetExcerptContent( const FString& Link, FExcerpt& Excerpt, bool bInSimpleText = false );	/** Allows a TAttribute to be set to control excerpt wrapat values from outside the parser. */	void SetWrapAt( TAttribute<float> InWrapAt );private:	bool bSimpleText = false;	/** UI Callbacks for the widgets */	FReply OnImageLinkClicked(FString Payload);		/** Adds the content text source to the scrollbox */	void AddContentToExcerpt(TSharedPtr<SVerticalBox> Box, const FString& ContentSource, FExcerpt& Excerpt);		/** Gets the dynamic brush for the given filename */	TSharedPtr<FSlateDynamicImageBrush> GetDynamicBrushFromImagePath(FString Filename);	/** Helper function which appends a content section to the scrollbox */	void AppendExcerpt(TSharedPtr<SVerticalBox> Box, TSharedRef<SWidget> Content);		/** Turns a series of symbols (or a single symbol) back to string format */	FString ConvertSymbolIntoAString(const FUDNToken& Token);	FString ConvertSymbolsIntoAString(const TArray<FUDNToken>& TokenList, int32 StartingAfterIndex = 0);	/** Given a line, converts it into UDN tokens, returning true if successful */	bool ParseLineIntoSymbols(int32 LineNumber, const FString& Line, TArray<FUDNToken>& SymbolList);	/** Given a line, convert it into an FUDNLine which can be used by Slate */	FUDNLine ParseLineIntoUDNContent(int32 LineNumber, const FString& Line);	bool LoadLink( const FString& Link, TArray<FString>& ContentLines );	TSharedRef< SWidget > GenerateExcerptContent( const FString& Link, FExcerpt& Excerpt, const TArray<FString>& ContentLines, int32 StartingLineIndex );	bool ParseSymbols( const FString& Link, const TArray<FString>& ContentLines, const FString& FullPath, TArray<FExcerpt>& OutExcerpts, FUDNPageMetadata& OutMetadata );	void HandleHyperlinkNavigate( FString AdditionalContent );	void NavigateToLink( FString AdditionalContent );private:	/** 	 * Parses a code link embedded in the doc.	 * 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.	 * [Project based link](CODELINK:Private/[PROJECT]File.cpp, 29, 5)	 * This will attempt to parse the active solution name and replace instances of [PROJECT] within this so	 * (CODELINK:Private/[PROJECT]Ball.cpp, 29, 5) will in a project called marble will equate to	 * <UE4ROOT>Marble/Source/Marble/Private/MarbleBall.cpp	 * [Explicit link](CODELINK:Templates/TP_Rolling/Source/TP_Rolling/Private/TP_Rolling.cpp will equate to	 * <UE4ROOT>Templates/TP_Rolling/Source/TP_Rolling/Private/TP_Rolling.cpp	 	 */	bool ParseCodeLink(FString &InternalLink);			/** 	 * Parses an asset link embedded in the doc.	 * Allows us to specify assets to either highlight or edit in the editor	 * (ASSETLINK:SELECT,MyCharacter)	 * This will highlight the MyCharacter asset in the content browser	 * (ASSETLINK:EDIT,MyCharacter)	 * This will edit the given asset in the appropriate editor window type.	 */	bool ParseAssetLink(FString &InternalLink);	FExtUDNParser( const TSharedRef< FParserConfiguration >& InConfiguration, const FDocumentationStyle& InStyle );	void Initialize();	/** A list of dynamic brushes we are using for the currently loaded tutorial */	TArray< TSharedPtr< FSlateDynamicImageBrush > > DynamicBrushesUsed;	/** Configuration details */	TSharedRef< FParserConfiguration > Configuration;	/** The styling we apply to generated widgets */	FDocumentationStyle Style;	/** A library of which tokens correspond to which series of strings */	struct FTokenPair	{		FTokenPair(FString InParseText, EUDNToken::Type InTokenType)			: ParseText(InParseText)			, TokenType(InTokenType) {}		FString ParseText;		EUDNToken::Type TokenType;	};	TArray<FTokenPair> TokenLibrary;	/** A library of which series of tokens correspond to which line types */	struct FTokenConfiguration	{		FTokenConfiguration(const TArray<EUDNToken::Type>& InTokenTypes, FUDNLine::Type InOutputLineType, bool bInAcceptTrailingContent = false)			: TokensAccepted(InTokenTypes)			, OutputLineType(InOutputLineType)			, bAcceptTrailingSymbolDumpAsContent(bInAcceptTrailingContent) {}				/** Tallies the total number of content tokens in this config */		int32 CalculatedExpectedContentStrings();		TArray<EUDNToken::Type> TokensAccepted;		FUDNLine::Type OutputLineType;		bool bAcceptTrailingSymbolDumpAsContent;	};	TArray<FTokenConfiguration> LineLibrary;	/** Documentation text wrapping control attribute */	TAttribute<float> WrapAt;	/** Documentation optional width control attribute */	TAttribute<FOptionalSize> ContentWidth;};}
 |