/// <summary>
        /// Create a syndication feed from the child pages of this page.
        /// </summary>
        /// <param name="session">a session</param>
        /// <param name="page">blocks of type ChildPage only</param>
        /// <param name="maxItems">max number of child pages to return</param>
        /// <param name="maxBlocks">limit the parsing of each page to the first maxBlocks blocks</param>
        /// <param name="stopBeforeFirstSubHeader">when true, stop parsing a page when a line containing a sub_header is found</param>
        /// <param name="cancel"></param>
        /// <returns>A SyndicationFeed containing one SyndicationItem per child page</returns>
        /// <remarks>
        /// Call this method with an existing page, which is the container for child pages.
        /// All child pages will go into this feed's items.
        ///
        /// The created feed has the title and id of the page.
        ///
        /// Are included only child pages which are not restricted with the "integration".
        /// </remarks>
        public static async Task <SyndicationFeed> GetSyndicationFeed(this NotionSession session, Page page, int maxItems = 50, int maxBlocks = 20, bool stopBeforeFirstSubHeader = true, CancellationToken cancel = default)
        {
            var childPages = await session.GetBlockChildren(page.Id, cancel : cancel)
                             .Where(b => b.Type == BlockTypes.ChildPage && b.ChildPage != null) //Both checks are redundant. We could keep only one.
                             .Take(maxItems)
                             .ToListAsync(cancel).ConfigureAwait(false);

            if (childPages.Count == 0)
            {
                return new SyndicationFeed {
                           LastUpdatedTime = DateTimeOffset.Now
                }
            }
            ;

            var feed = await session.GetSyndicationFeed(childPages, maxBlocks, stopBeforeFirstSubHeader, cancel).ConfigureAwait(false);

            //"workspace" data not available in API
            //feed.Id = space.Id.ToString("N");
            //feed.Title = new TextSyndicationContent(space.Name);
            //feed.Description = new TextSyndicationContent(space.Domain);
            feed.Id    = page.Id;
            feed.Title = new TextSyndicationContent(page.Title?.Title?.FirstOrDefault()?.PlainText);
            return(feed);
        }
        /// <summary>
        /// Create a syndication feed from a list of page
        /// </summary>
        /// <param name="session">a session</param>
        /// <param name="childPages">blocks of type ChildPage only</param>
        /// <param name="maxBlocks">limits the parsing of each page to the first maxBlocks blocks</param>
        /// <param name="stopBeforeFirstSubHeader">when true, stop parsing a page when a line containing a sub_header is found</param>
        /// <param name="cancel"></param>
        /// <returns>A SyndicationFeed containing one SyndicationItem per page</returns>
        /// <remarks>
        /// The created feed has no title/description
        /// </remarks>
        public static async Task <SyndicationFeed> GetSyndicationFeed(this NotionSession session, IEnumerable <Block> childPages, int maxBlocks = 20, bool stopBeforeFirstSubHeader = true, CancellationToken cancel = default)
        {
            var feedItems    = new List <SyndicationItem>();
            var htmlRenderer = new HtmlRenderer();

            foreach (var page in childPages)
            {
                if (page.Type != BlockTypes.ChildPage)
                {
                    throw new ArgumentException("All childPages must be of type BlockTypes.ChildPage", nameof(childPages));
                }

                //get blocks and extract an html content
                var blocks = await session.GetBlockChildren(page.Id, cancel : cancel)
                             .Take(maxBlocks)
                             .ToListAsync(cancel).ConfigureAwait(false);

                var content = htmlRenderer.GetHtml(blocks, stopBeforeFirstSubHeader);
                var title   = page.ChildPage !.Title;
                var pageUri = NotionUtils.GetPageUri(page.Id, title);

                var item = new SyndicationItem(title, content, pageUri)
                {
                    Id              = page.Id,
                    BaseUri         = pageUri,
                    Summary         = new TextSyndicationContent(content),
                    PublishDate     = page.CreatedTime,
                    LastUpdatedTime = page.LastEditedTime,
                };

                // Property not yet available in API
                // if (!String.IsNullOrWhiteSpace(page.Format?.PageIcon))
                // {
                //     if(Uri.TryCreate(page.Format.PageIcon, UriKind.Absolute, out _))
                //         item.AttributeExtensions.Add(new XmlQualifiedName("iconUrl"), pageBlock.Format.PageIcon);
                //     else
                //         item.AttributeExtensions.Add(new XmlQualifiedName("iconString"), pageBlock.Format.PageIcon);
                // }

                feedItems.Add(item);
            }

            var feed = new SyndicationFeed(feedItems)
            {
                LastUpdatedTime = feedItems.DefaultIfEmpty().Max(item => item?.LastUpdatedTime ?? DateTimeOffset.MinValue),
            };

            return(feed);
        }
        public static async Task <string> GetHtml(this NotionSession session, Page page, CancellationToken cancel = default)
        {
            var blocks = await session.GetBlockChildren(page.Id, cancel : cancel)
                         .Where(b => b.Type != BlockTypes.ChildPage)
                         .ToListAsync(cancel).ConfigureAwait(false);

            if (blocks.Count == 0)
            {
                return(string.Empty);
            }

            var htmlRenderer = new HtmlRenderer();

            return(htmlRenderer.GetHtml(blocks));
        }