/// <inheritdoc /> public FlexiAlertBlock Create(BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiAlertBlockOptions flexiAlertBlockOptions, IFlexiAlertBlocksExtensionOptions flexiAlertBlocksExtensionOptions) = _optionsService.CreateOptions(blockProcessor); // Block name string blockName = ResolveBlockName(flexiAlertBlockOptions.BlockName); // Type string type = ResolveType(flexiAlertBlockOptions.Type); // Icon string icon = ResolveIcon(flexiAlertBlockOptions.Icon, type, flexiAlertBlocksExtensionOptions.Icons); // Create block return(new FlexiAlertBlock(blockName, type, icon, flexiAlertBlockOptions.Attributes, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, blockProcessor.Line.End) // Might be the only line, parser will update end if there are more lines // Line is assigned by BlockProcessor }); }
internal virtual FlexiCodeBlock CreateCore(ProxyLeafBlock proxyLeafBlock, BlockProcessor blockProcessor) { if (proxyLeafBlock == null) { throw new ArgumentNullException(nameof(proxyLeafBlock)); } (IFlexiCodeBlockOptions flexiCodeBlockOptions, IFlexiCodeBlocksExtensionOptions _) = _optionsService.CreateOptions(blockProcessor); // Code StringLineGroup lines = proxyLeafBlock.Lines; string code = proxyLeafBlock.Lines.ToString(); int codeNumLines = lines.Count; // Block name string blockName = ResolveBlockName(flexiCodeBlockOptions.BlockName); // Syntax highlighter SyntaxHighlighter syntaxHighlighter = flexiCodeBlockOptions.SyntaxHighlighter; ValidateSyntaxHighlighter(syntaxHighlighter); // Line numbers ReadOnlyCollection <NumberedLineRange> lineNumbers = TryCreateSortedLineRanges(flexiCodeBlockOptions.LineNumbers, codeNumLines); ValidateSortedLineNumbers(lineNumbers, codeNumLines); // Highlighted lines ReadOnlyCollection <LineRange> highlightedLines = TryCreateSortedLineRanges(flexiCodeBlockOptions.HighlightedLines, codeNumLines); // Highlighted phrases ReadOnlyCollection <Phrase> highlightedPhrases = ResolveHighlightedPhrases(code, flexiCodeBlockOptions.HighlightedPhrases); // Rendering mode FlexiCodeBlockRenderingMode renderingMode = flexiCodeBlockOptions.RenderingMode; ValidateRenderingMode(renderingMode); return(new FlexiCodeBlock( blockName, flexiCodeBlockOptions.Title, flexiCodeBlockOptions.CopyIcon, flexiCodeBlockOptions.RenderHeader, flexiCodeBlockOptions.Language, code, codeNumLines, syntaxHighlighter, lineNumbers, flexiCodeBlockOptions.OmittedLinesIcon, highlightedLines, highlightedPhrases, renderingMode, flexiCodeBlockOptions.Attributes, proxyLeafBlock.Parser) { Line = proxyLeafBlock.Line, Column = proxyLeafBlock.Column, Span = proxyLeafBlock.Span }); }
/// <summary> /// Creates a <see cref="FlexiIncludeBlock"/>. /// </summary> /// <param name="proxyJsonBlock">The <see cref="ProxyJsonBlock"/> containing data for the <see cref="FlexiIncludeBlock"/>.</param> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiIncludeBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="proxyJsonBlock"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> /// <exception cref="OptionsException">Thrown if an option is invalid.</exception> /// <exception cref="InvalidOperationException">Thrown if a <see cref="FlexiIncludeBlock"/> cycle is found.</exception> /// <exception cref="BlockException">Thrown if an exception is thrown while processing the <see cref="FlexiIncludeBlock"/>'s included content.</exception> public FlexiIncludeBlock Create(ProxyJsonBlock proxyJsonBlock, BlockProcessor blockProcessor) { (IFlexiIncludeBlockOptions flexiIncludeBlockOptions, IFlexiIncludeBlocksExtensionOptions flexiIncludeBlocksExtensionOptions) = _optionsService. CreateOptions(blockProcessor, proxyJsonBlock); // Source string source = flexiIncludeBlockOptions.Source; ValidateSource(source); // Type FlexiIncludeType type = flexiIncludeBlockOptions.Type; ValidateType(type); // Cache directory string cacheDirectory = ResolveAndValidateCacheDirectory(flexiIncludeBlockOptions.Cache, flexiIncludeBlockOptions.CacheDirectory); // Parent FlexiIncludeBlock parent = ResolveParent(blockProcessor); // Containing source string containingSource = ResolveContainingSource(parent); // Source absolute URI Uri sourceAbsoluteUri = ResolveSourceAbsoluteUri(source, flexiIncludeBlocksExtensionOptions.BaseUri, parent); // Create block var flexiIncludeBlock = new FlexiIncludeBlock(sourceAbsoluteUri, flexiIncludeBlockOptions.Clippings, type, cacheDirectory, parent, containingSource, proxyJsonBlock.Parser) { Column = proxyJsonBlock.Column, Line = proxyJsonBlock.Line, Span = proxyJsonBlock.Span }; parent?.Children.Add(flexiIncludeBlock); ProcessFlexiIncludeBlock(flexiIncludeBlock, proxyJsonBlock, blockProcessor); return(null); }
/// <summary> /// Creates a <see cref="FlexiBannerBlock"/>. /// </summary> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiBannerBlock"/>.</param> /// <param name="blockParser">The <see cref="BlockParser"/> parsing the <see cref="FlexiBannerBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> public override FlexiBannerBlock Create(BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiBannerBlockOptions flexiBannerBlockOptions, IFlexiBannerBlocksExtensionOptions _) = _optionsService.CreateOptions(blockProcessor); // Block name string blockName = ResolveBlockName(flexiBannerBlockOptions.BlockName); // Create block return(new FlexiBannerBlock(blockName, flexiBannerBlockOptions.LogoIcon, flexiBannerBlockOptions.BackgroundIcon, flexiBannerBlockOptions.Attributes, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, 0) // MultipartBlockParser will update end // Line is assigned by BlockProcessor }); }
/// <summary> /// Creates a <see cref="FlexiVideoBlock"/>. /// </summary> /// <param name="proxyJsonBlock">The <see cref="ProxyJsonBlock"/> containing data for the <see cref="FlexiVideoBlock"/>.</param> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiVideoBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="proxyJsonBlock"/> is <c>null</c>.</exception>S /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> /// <exception cref="OptionsException">Thrown if an option is invalid.</exception> /// <exception cref="InvalidOperationException">Thrown if FFmpeg is not available.</exception> /// <exception cref="InvalidOperationException">Thrown if an exception is thrown while attempting to run FFmpeg.</exception> /// <exception cref="InvalidOperationException">Thrown if an FFmpeg run fails (exit code > 0).</exception> /// <exception cref="InvalidOperationException">Thrown if metadata retrieved from the video is invalid.</exception> public override FlexiVideoBlock Create(ProxyJsonBlock proxyJsonBlock, BlockProcessor blockProcessor) { (IFlexiVideoBlockOptions flexiVideoBlockOptions, IFlexiVideoBlocksExtensionOptions flexiVideoBlocksExtensionOptions) = _optionsService. CreateOptions(blockProcessor, proxyJsonBlock); // Block name string blockName = ResolveBlockName(flexiVideoBlockOptions.BlockName); // Src string fileName = ValidateSrcAndResolveFileName(flexiVideoBlockOptions); // Type string type = ResolveType(fileName, flexiVideoBlockOptions.Type, flexiVideoBlocksExtensionOptions.MimeTypes); // Enable file operations double width = flexiVideoBlockOptions.Width; double height = flexiVideoBlockOptions.Height; double duration = flexiVideoBlockOptions.Duration; bool generatePoster = flexiVideoBlockOptions.GeneratePoster; string poster = flexiVideoBlockOptions.Poster; bool enableFileOperations = ResolveEnableFileOperations(flexiVideoBlockOptions.EnableFileOperations, flexiVideoBlocksExtensionOptions.LocalMediaDirectory, generatePoster, poster, width, height, duration); // Source local absolute path string localAbsolutePath = ResolveLocalAbsolutePath(enableFileOperations, fileName, flexiVideoBlocksExtensionOptions); // Dimensions and duration (double resolvedWidth, double resolvedHeight, double aspectRatio, double resolvedDuration) = ResolveDimensionsAndDuration(localAbsolutePath, width, height, duration); // Poster string src = flexiVideoBlockOptions.Src; string resolvedPoster = ResolvePoster(localAbsolutePath, src, poster, generatePoster); // Create block return(new FlexiVideoBlock(blockName, src, type, resolvedPoster, resolvedWidth, resolvedHeight, aspectRatio, resolvedDuration, flexiVideoBlockOptions.Spinner, flexiVideoBlockOptions.PlayIcon, flexiVideoBlockOptions.PauseIcon, flexiVideoBlockOptions.FullscreenIcon, flexiVideoBlockOptions.ExitFullscreenIcon, flexiVideoBlockOptions.ErrorIcon, flexiVideoBlockOptions.Attributes, proxyJsonBlock.Parser) { Column = proxyJsonBlock.Column, Line = proxyJsonBlock.Line, Span = proxyJsonBlock.Span }); }
/// <summary> /// Creates a <see cref="FlexiQuoteBlock"/>. /// </summary> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiQuoteBlock"/>.</param> /// <param name="blockParser">The <see cref="BlockParser"/> parsing the <see cref="FlexiQuoteBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> public override FlexiQuoteBlock Create(BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiQuoteBlockOptions flexiQuoteBlockOptions, IFlexiQuoteBlocksExtensionOptions _) = _optionsService. CreateOptions(blockProcessor); // Block name string blockName = ResolveBlockName(flexiQuoteBlockOptions.BlockName); // Create block var flexiQuoteBlock = new FlexiQuoteBlock(blockName, flexiQuoteBlockOptions.Icon, flexiQuoteBlockOptions.CiteLink, flexiQuoteBlockOptions.Attributes, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, 0) // MultipartBlockParser will update end // Line is assigned by BlockProcessor }; // Subscribe to ProcessInlinesEnd event - LinkInlines only exist after inline processing is done flexiQuoteBlock.ProcessInlinesEnd += ExtractCiteUrl; return(flexiQuoteBlock); }
/// <inheritdoc /> public FlexiTableBlock Create(ProxyTableBlock proxyTableBlock, BlockProcessor blockProcessor) { (IFlexiTableBlockOptions flexiTableBlockOptions, IFlexiTableBlocksExtensionOptions _) = _optionsService. CreateOptions(blockProcessor); // Block name string blockName = ResolveBlockName(flexiTableBlockOptions.BlockName); // Type FlexiTableType type = flexiTableBlockOptions.Type; ValidateType(type); // Create block return(CreateFlexiTableBlock(blockName, type, flexiTableBlockOptions.Attributes, proxyTableBlock, blockProcessor)); }
/// <summary> /// Creates a <see cref="FlexiFigureBlock"/>. /// </summary> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiFigureBlock"/>.</param> /// <param name="blockParser">The <see cref="BlockParser"/> parsing the <see cref="FlexiFigureBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> public override FlexiFigureBlock Create(BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiFigureBlockOptions flexiFigureBlockOptions, IFlexiFigureBlocksExtensionOptions _) = _optionsService.CreateOptions(blockProcessor); // Block name string blockName = ResolveBlockName(flexiFigureBlockOptions.BlockName); // Figure number int figureNumber = GetFlexiFigureBlockNumber(blockProcessor); // ID ReadOnlyDictionary <string, string> attributes = flexiFigureBlockOptions.Attributes; string id = ResolveID(flexiFigureBlockOptions.GenerateID, figureNumber, attributes); // ReferenceLinkable bool referenceLinkable = ResolveReferenceLinkable(flexiFigureBlockOptions.ReferenceLinkable, id); // LinkLabelContent specified string linkLabelContent = flexiFigureBlockOptions.LinkLabelContent; bool linkLabelContentSpecified = IsLinkLabelContentSpecified(linkLabelContent); // Name bool renderName = flexiFigureBlockOptions.RenderName; string name = ResolveName(referenceLinkable, linkLabelContentSpecified, renderName, figureNumber); // LinkLabelContent string resolvedLinkLabelContent = ResolveLinkLabelContent(referenceLinkable, linkLabelContentSpecified, name, linkLabelContent); // Create block var result = new FlexiFigureBlock(blockName, name, renderName, resolvedLinkLabelContent, id, attributes, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, 0) // MultipartBlockParser will update end // Line is assigned by BlockProcessor }; // Reference-linking SetupReferenceLinking(result, referenceLinkable, blockProcessor); return(result); }
/// <summary> /// Creates a <see cref="ProxyFlexiTabsBlock"/>. /// </summary> /// <param name="openingFenceIndent">The indent of the opening fence.</param> /// <param name="openingFenceCharCount">The number of characters in the opening fence.</param> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="ProxyFlexiTabsBlock"/>.</param> /// <param name="blockParser">The <see cref="BlockParser"/> parsing the <see cref="ProxyFlexiTabsBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> public override ProxyFlexiTabsBlock CreateProxyFencedBlock(int openingFenceIndent, int openingFenceCharCount, BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiTabsBlockOptions flexiTabsBlockOptions, IFlexiTabsBlocksExtensionOptions _) = _optionsService.CreateOptions(blockProcessor); // Default tab options ValidateDefaultTabOptions(flexiTabsBlockOptions); return(new ProxyFlexiTabsBlock(flexiTabsBlockOptions, openingFenceIndent, openingFenceCharCount, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, 0) // FencedBlockParser will update end // Line is assigned by BlockProcessor }); }
/// <summary> /// Creates a <see cref="FlexiPictureBlock"/>. /// </summary> /// <param name="proxyJsonBlock">The <see cref="ProxyJsonBlock"/> containing data for the <see cref="FlexiPictureBlock"/>.</param> /// <param name="blockProcessor">The <see cref="BlockProcessor"/> processing the <see cref="FlexiPictureBlock"/>.</param> /// <exception cref="ArgumentNullException">Thrown if <paramref name="proxyJsonBlock"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException">Thrown if <paramref name="blockProcessor"/> is <c>null</c>.</exception> /// <exception cref="OptionsException">Thrown if an option is invalid.</exception> /// <exception cref="InvalidOperationException">Thrown if dimensions cannot be read from the local image file.</exception> public override FlexiPictureBlock Create(ProxyJsonBlock proxyJsonBlock, BlockProcessor blockProcessor) { (IFlexiPictureBlockOptions flexiPictureBlockOptions, IFlexiPictureBlocksExtensionOptions flexiPictureBlocksExtensionOptions) = _optionsService. CreateOptions(blockProcessor, proxyJsonBlock); // Block name string blockName = ResolveBlockName(flexiPictureBlockOptions.BlockName); // Src string fileName = ValidateSrcAndResolveFileName(flexiPictureBlockOptions); // Enable file operations double height = flexiPictureBlockOptions.Height; double width = flexiPictureBlockOptions.Width; bool enableFileOperations = ResolveEnableFileOperations(flexiPictureBlockOptions.EnableFileOperations, flexiPictureBlocksExtensionOptions.LocalMediaDirectory, width, height); // Source local absolute path string localAbsolutePath = ResolveLocalAbsolutePath(enableFileOperations, fileName, flexiPictureBlocksExtensionOptions); // Resolve intrinsic width and height (double resolvedWidth, double resolvedHeight, double aspectRatio) = ResolveDimensions(localAbsolutePath, width, height); // Create block return(new FlexiPictureBlock(blockName, flexiPictureBlockOptions.Src, flexiPictureBlockOptions.Alt, flexiPictureBlockOptions.Lazy, resolvedWidth, resolvedHeight, aspectRatio, flexiPictureBlockOptions.ExitFullscreenIcon, flexiPictureBlockOptions.ErrorIcon, flexiPictureBlockOptions.Spinner, flexiPictureBlockOptions.Attributes, proxyJsonBlock.Parser) { Column = proxyJsonBlock.Column, Line = proxyJsonBlock.Line, Span = proxyJsonBlock.Span }); }
/// <inheritdoc /> public FlexiSectionBlock Create(int level, BlockProcessor blockProcessor, BlockParser blockParser) { (IFlexiSectionBlockOptions flexiSectionBlockOptions, IFlexiSectionBlocksExtensionOptions _) = _optionsService.CreateOptions(blockProcessor); // Level ValidateLevel(level); // Block name string blockName = ResolveBlockName(flexiSectionBlockOptions.BlockName); // Element SectioningContentElement element = flexiSectionBlockOptions.Element; ValidateElement(element); // Rendering mode FlexiSectionBlockRenderingMode renderingMode = flexiSectionBlockOptions.RenderingMode; ValidateRenderingMode(renderingMode); // Create FlexiSectionBlock var flexiSectionBlock = new FlexiSectionBlock(blockName, element, flexiSectionBlockOptions.LinkIcon, renderingMode, level, flexiSectionBlockOptions.Attributes, blockParser) { Column = blockProcessor.Column, Span = new SourceSpan(blockProcessor.Start, blockProcessor.Line.End), // TODO span should include children // BlockProcessor will assign Line }; // Create FlexiSectionHeadingBlock FlexiSectionHeadingBlock flexiSectionHeadingBlock = _flexiSectionHeadingBlockFactory.Create(blockProcessor, flexiSectionBlockOptions, blockParser); flexiSectionBlock.Add(flexiSectionHeadingBlock); // Close FlexiSectionBlocks with same or lower levels UpdateOpenFlexiSectionBlocks(blockProcessor, flexiSectionBlock); return(flexiSectionBlock); }