public function visitTextFrame(IdmlTextFrame $element, $outer_depth = 0)
 {
     // For the outermost TextFrame whose parent is IdmlPage, do not do the special anchor processing
     $parentElement = $element->parentIdmlObject();
     if ($element->parentIdmlObject() == null) {
         $this->addPageElement("<!-- OUTERTEXTFRAME {$element->story->UID} -->", $outer_depth, '');
         return;
         // yes visit children
     } else {
         $stack = $this->getAncestors($element, 'IdmlPage');
         // close all open tags back to the root
         $this->rewind($stack, $outer_depth);
         $inner_depth = get_class($element->parentIdmlObject()) == 'IdmlCharacterRange' ? $outer_depth - 3 : $outer_depth;
         $this->addPageElement("<!-- ANCHORED TEXTFRAME {$element->story->UID} -->", $inner_depth, '');
         $this->addPageElement("<div data-idml='IdmlTextFrame {$element->UID}'>", $inner_depth);
         $this->addPageElement("<!-- ANCHOR {$element->story->UID} -->", $inner_depth + 1, '');
         // Create a new producer for recursion . . .
         $thisClass = get_class($this);
         assert($thisClass == 'IdmlProduceFixedLayout' || $thisClass == 'IdmlProduceReflowable' || $thisClass == 'IdmlProduceHtmlDiagnostic');
         $currentRecursivePageNumber = $this->pageNumber;
         $htmlProducer = new $thisClass($currentRecursivePageNumber);
         // . . . then walk the tree starting from the current text frame's story . . .
         if ($element->story && $element->visible) {
             $element->story->accept($htmlProducer, $inner_depth + 1);
         }
         // . . . and finally stuff the content that _it_ produces back into this object. . .
         $innerContent = $htmlProducer->getBodyContent();
         $diagnosticContent = $htmlProducer->getDiagnosticContent();
         $this->addPageElement($innerContent, 0, $diagnosticContent);
         // . . . and copy the page number of the inner object to the outer object.
         $this->pageNumber = $htmlProducer->pageNumber;
         $this->addPageElement("<!-- /ANCHOR {$element->story->UID} -->", $inner_depth + 1, '');
         $this->addPageElement("</div><!-- IdmlTextFrame {$element->UID}-->", $inner_depth);
         $this->addPageElement("<!-- /ANCHORED TEXTFRAME {$element->story->UID} -->", $inner_depth, '');
         // reopen all tags from the root down to where we were before we were interrupted
         $this->fastForward($stack, $outer_depth);
         // Important: Instruct IdmlTextFrame not to continue any deeper
         return 'do not visit children';
     }
 }
Example #2
0
 /**
  * Parse DOM.
  * 
  * @param DOMDocument $doc
  */
 private function parse(DOMDocument $doc)
 {
     $xpath = new DOMXPath($doc);
     $q = "//idPkg:{$this->xmlRootName}/{$this->xmlRootName}";
     $nodes = $xpath->query($q);
     $pageNode = $nodes->item(0);
     $attributes = $pageNode->attributes;
     $this->UID = $attributes->getNamedItem('Self')->value;
     $itemTransform = $attributes->getNamedItem('ItemTransform')->value;
     $this->transformation = new IdmlTransformation($itemTransform);
     $this->pageCount = (int) $attributes->getNamedItem('PageCount')->value;
     if ($pageNode->hasAttribute('BindingLocation')) {
         $bindingLocation = (int) $pageNode->getAttribute('BindingLocation');
     } else {
         // this happens with MasterSpreads which do not have a binding location.
         $bindingLocation = -1;
     }
     // First construct the pages (typically one or two pages per spread)
     // although more than two are technically allowed.
     // We need to have pages loaded first.
     $q = "//idPkg:{$this->xmlRootName}/{$this->xmlRootName}//Page";
     $nodes = $xpath->query($q);
     foreach ($nodes as $pageNode) {
         $newPage = new IdmlPage($this);
         $newPage->parse($pageNode);
         $this->pages[] = $newPage;
     }
     // Process children text frames and rectangles.
     $spreadNodes = $doc->getElementsByTagName($this->xmlRootName);
     $spreadNode = $spreadNodes->item(1);
     // Child nodes.
     foreach ($spreadNode->childNodes as $element) {
         $nodeSelf = '';
         if ($element->nodeType == XML_ELEMENT_NODE) {
             /*@var $element DomNode*/
             //get the element's id if possible and make sure it is not to be hidden before we parse it
             $selfIdNode = $element->attributes->getNamedItem('Self');
             if ($selfIdNode) {
                 $nodeSelf = $selfIdNode->nodeValue;
             }
         }
         if ($nodeSelf && array_key_exists($nodeSelf, $this->idmlPackage->chaucerHidden)) {
             error_log('Processing Spread Page, hiding ' . $element->nodeName . ' ' . $nodeSelf . ' ' . __FILE__ . ' Line ' . __LINE__);
         } elseif ($element->nodeType == XML_ELEMENT_NODE) {
             switch ($element->nodeName) {
                 case 'Rectangle':
                     // @TODO - determine whether spans should be used for rectangles parallel to the axes, and code accordingly
                     //                        $rectangle = new IdmlRectangle();
                     $rectangle = new IdmlPolygon();
                     $rectangle->parse($element);
                     $this->dropElementIntoPage($rectangle);
                     break;
                 case 'TextFrame':
                     $newTextFrame = new IdmlTextFrame();
                     $newTextFrame->parse($element);
                     $this->dropElementIntoPage($newTextFrame);
                     $pageUID = $newTextFrame->page != null ? $newTextFrame->page->UID : '000';
                     // And now for some hyperlink management:
                     $hyperlinkMgr = IdmlHyperlinkManager::getInstance();
                     // Update the destination page names for links to anchors.
                     // Refs to the anchors are stored during processing of children, but we don't have the UIDs until the text frame is fully parsed.
                     $hyperlinkMgr->updateDestinationPages($newTextFrame->UID, $pageUID);
                     // Also, map the page UID to the text frame UID so the destination page name can be determined for fixed layout.
                     $hyperlinkMgr->saveTextFrameUID($newTextFrame->UID, $pageUID);
                     break;
                 case 'Group':
                     $group = new IdmlGroup();
                     $group->parse($element);
                     $this->dropElementIntoPage($group);
                     break;
                 case 'Polygon':
                     $polygon = new IdmlPolygon();
                     $polygon->parse($element);
                     $this->dropElementIntoPage($polygon);
                     break;
                 case 'Oval':
                     $oval = new IdmlOval();
                     $oval->parse($element);
                     $this->dropElementIntoPage($oval);
                     break;
                 case 'GraphicLine':
                     $line = new IdmlGraphicLine();
                     $line->parse($element);
                     $this->dropElementIntoPage($line);
                     break;
                 default:
                     // Placeholder: no default action at this time
                     break;
             }
         }
     }
 }
 /**
  * Create an HTML aside from the IDML TextFrame.
  * @param IdmlTextFrame $element
  * @param int $outer_depth
  */
 protected function createAside(IdmlTextFrame $element, $outer_depth = 0)
 {
     $inner_depth = get_class($element->parentIdmlObject()) == 'IdmlCharacterRange' ? $outer_depth - 3 : $outer_depth;
     $this->addPageElement("<!-- ANCHOR {$element->story->UID} -->", $inner_depth + 1, '');
     $this->writeAsideBegin($element, $inner_depth + 1);
     // Create a new producer for recursion . . .
     // NOTE: Logic using a 2nd producer has been eliminated. We think it is no longer effective
     //       Code is left in place in case things go horribly awry.
     //        $thisClass = get_class($this);
     //        $currentRecursivePageNumber = $this->pageNumber;
     //        $htmlProducer = new $thisClass($currentRecursivePageNumber);
     // . . . then walk the tree starting from the current text frame's story . . .
     if ($element->story && $element->visible) {
         $element->story->accept($this, $outer_depth + 1);
         //            $element->story->accept($htmlProducer, $inner_depth+1);
     }
     // . . . and finally stuff the content that _it_ produces back into this object
     // Copy the page elements to a new array first to prevent side effects
     //        $innerContent = $htmlProducer->getPageElements();
     //        $pageElements = $this->pageElements;
     //        $this->pageElements = array_merge($pageElements, $innerContent);
     //        $diagnosticContent = $htmlProducer->getDiagnosticPageElements();
     //        $diagnosticPageElements = $this->diagnosticPageElements;
     //        $this->diagnosticPageElements = array_merge($diagnosticPageElements, $diagnosticContent);
     $this->writeAsideEnd($outer_depth + 1);
     $this->addPageElement("<!-- /ANCHOR {$element->story->UID} -->", $inner_depth + 1, '');
     if (!is_null($element->rotationOffset)) {
         $this->addPageElement('<div style="height:' . $element->rotationOffset . 'px;">', 0);
         $this->addPageElement('</div>', 0);
         $element->rotationOffset = null;
     }
 }
Example #4
0
 public function visitTextFrame(IdmlTextFrame $element, $depth = 0)
 {
     /* find the parent and if it is a character range, drop that from the parent list */
     $parentElement = $element->parentIdmlObject();
     if (is_a($parentElement, "IdmlCharacterRange") && count($this->parentStack) > 3) {
         $element->attributes["_pxe_stashed_parent"] = array_pop($this->parentStack);
     }
 }