3 namespace BookStack\Entities\Tools;
5 use BookStack\Util\HtmlDocument;
8 class PageIncludeParser
10 protected static string $includeTagRegex = "/{{@\s?([0-9].*?)}}/";
12 public function __construct(
13 protected string $pageHtml,
14 protected Closure $pageContentForId,
18 public function parse(): string
20 $html = new HtmlDocument($this->pageHtml);
22 $includeHosts = $html->queryXPath("//body//*[contains(text(), '{{@')]");
23 $node = $includeHosts->item(0);
25 // One of the direct child textnodes of the "$includeHosts" should be
26 // the one with the include tag within.
27 $textNode = $node->childNodes->item(0);
30 // Hunt down the specific text nodes with matches
31 // Split out tag text node from rest of content
32 // Fetch tag content->
33 // If range or top-block: delete tag text node, [Promote to top-block], delete old top-block if empty
34 // If inline: Replace current text node with new text or elem
35 // !! "Range" or "inline" status should come from tag parser and content fetcher, not guessed direct from content
36 // since we could have a range of inline elements
38 // [Promote to top-block]
40 // Can throw in before or after current top-block depending on relative position
41 // Could [Split] top-block but complex past a single level depth.
42 // Maybe [Split] if one level depth, otherwise default to before/after block
43 // Should work for the vast majority of cases, and not for those which would
44 // technically be invalid in-editor anyway.
47 // Copy original top-block node type and attrs (apart from ID)
48 // Move nodes after promoted tag-node into copy
49 // Insert copy after original (after promoted top-block eventually)
51 // Notes: May want to eventually parse through backwards, which should avoid issues
52 // in changes affecting the next tag, where tags may be in the same/adjacent nodes.
55 return $html->getBodyInnerHtml();