Beispiel #1
0
        /// <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
            });
        }
Beispiel #3
0
        /// <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
            });
        }
Beispiel #5
0
        /// <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
            });
        }
Beispiel #6
0
        /// <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);
        }
Beispiel #9
0
        /// <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
            });
        }
Beispiel #10
0
        /// <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
            });
        }
Beispiel #11
0
        /// <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);
        }