protected function typographyFill($colorRef, $fillTint) { $enableFill = array_key_exists('EnableFill', $this->idmlContext) ? $this->idmlContext['EnableFill'] : 'true'; if ($enableFill == 'false') { $this->registerCSS('color', 'transparent'); return; } $handle = IdmlDeclarationManager::getInstance()->declaredColorHandler; list($colorRefType, $colorRefName) = explode('/', $colorRef); switch ($colorRefType) { case 'Swatch': if ($colorRefName == 'None') { $this->registerCSS('color', 'transparent'); } break; case 'Color': case 'Ink': case 'MixedInk': case 'Tint': $rgbRaw = $handle->colorRefToRGB($colorRef); $rgbTint = $handle->applyTintToRGB($rgbRaw, $fillTint); $hexColor = $handle->rgbAsHex($rgbTint); $this->registerCSS('color', $hexColor); break; case 'Gradient': $hexColor = $handle->firstColorAsCSS($colorRef); $this->registerCSS('color', $hexColor); break; case 'PastedSmoothShade': case 'MixedInkGroup': default: break; } }
public function parse(DOMElement $node) { $manager = IdmlDeclarationManager::getInstance(); foreach ($node->childNodes as $child) { if ($child->nodeType != XML_ELEMENT_NODE) { continue; } if ($child->nodeName == $this->groupTemplateName) { $classname = 'Idml' . $this->groupTemplateName; // something like 'IdmlParagraphStyleGroup' $obj = new $classname(); $name = $obj->parse($child); $manager->addDeclaredStyleGroup($name, $obj); $this->children[] = $name; } else { if ($child->nodeName == $this->styleTemplateName) { $classname = 'Idml' . $this->styleTemplateName; // something like 'IdmlParagraphStyle' $obj = new $classname(); $obj->parse($child); $name = $obj->idmlKeyValues['Self']; $manager->addDeclaredStyle($name, $obj); $this->children[] = $name; } else { CakeLog::debug("[IdmlDeclaredStyleGroup::parse] Unhandled tag <{$child->nodeName}>"); } } } return $node->hasAttribute('Self') ? $node->getAttribute('Self') : ''; }
/** * Constructor. * @var integer $currentRecursivePageNumber since this class is used recursively, we need to keep track * of which page we are on when we construct a new instance. Use 1 for the outermost instance. */ public function __construct($currentRecursivePageNumber = 1) { $this->pageElements = array(); $this->diagnosticPageElements = array(); $this->pageNumber = $currentRecursivePageNumber; $this->declarationMgr = IdmlDeclarationManager::getInstance(); $this->pageNameXref = array(); $this->currSvgUID = null; }
public function __construct($idmlKeyValues, IdmlParagraphRange $paragraph) { $this->parentParagraph = $paragraph; $idmlCharStyle = $idmlKeyValues['AppliedCharacterStyle']; $this->charStyle = IdmlDeclarationManager::getInstance()->declaredStyles[$idmlCharStyle]->getClassName(); $this->numTimes = (int) $idmlKeyValues['Repetition']; $this->delimiter = $idmlKeyValues['Delimiter']; $this->inclusive = $idmlKeyValues['Inclusive'] == 'true'; $this->assignDelimValues($this->delimiter); $this->numFound = 0; }
/** * The parse function is the starting point for parsing the Styles.xml file. */ public function load($filename) { $manager = IdmlDeclarationManager::getInstance(); // Read the /Resources/Styles.xml file into a DOMDocument if (!file_exists($filename)) { CakeLog::debug("[IdmlDeclarationParser::load] Filename not found {$filename}"); return false; } $doc = new DOMDocument(); if ($doc->load($filename) === false) { CakeLog::debug("[IdmlDeclarationParser::load] Unable to read {$filename}"); return false; } $xpath = new DOMXPath($doc); // Recursively read each of the style groups and their hierarchy of styles $nodes = $xpath->query('//idPkg:Styles/RootCharacterStyleGroup'); if ($nodes->length > 0) { $obj = new IdmlCharacterStyleGroup(); $name = $obj->parse($nodes->item(0)); $manager->addDeclaredStyleGroup($name, $obj); } $nodes = $xpath->query('//idPkg:Styles/RootParagraphStyleGroup'); if ($nodes->length > 0) { $obj = new IdmlParagraphStyleGroup(); $name = $obj->parse($nodes->item(0)); $manager->addDeclaredStyleGroup($name, $obj); } $nodes = $xpath->query('//idPkg:Styles/RootObjectStyleGroup'); if ($nodes->length > 0) { $obj = new IdmlObjectStyleGroup(); $name = $obj->parse($nodes->item(0)); $manager->addDeclaredStyleGroup($name, $obj); } $nodes = $xpath->query('//idPkg:Styles/RootTableStyleGroup'); if ($nodes->length > 0) { $obj = new IdmlTableStyleGroup(); $name = $obj->parse($nodes->item(0)); $manager->addDeclaredStyleGroup($name, $obj); } $nodes = $xpath->query('//idPkg:Styles/RootCellStyleGroup'); if ($nodes->length > 0) { $obj = new IdmlCellStyleGroup(); $name = $obj->parse($nodes->item(0)); $manager->addDeclaredStyleGroup($name, $obj); } // Using each style's "BasedOn" property, flatten the hierarchy so that each style has all of it's parent's properties. $manager->resolveAll(); // Turn all properties which had duplicate names into an arrays foreach ($manager->declaredStyles as $styleName => $declaredStyle) { self::arrayifyDupes($styleName, $declaredStyle); } }
public function convert() { $underlineOnStr = array_key_exists('Underline', $this->idmlContext) ? $this->idmlContext['Underline'] : 'false'; $underlineOn = $underlineOnStr == 'true'; $backColorName = array_key_exists('Properties::UnderlineColor', $this->idmlContext) ? $this->idmlContext['Properties::UnderlineColor'] : false; $underlineOffset = array_key_exists('UnderlineOffset', $this->idmlContext) ? $this->idmlContext['UnderlineOffset'] : false; // This code addresses the use case where underlining is used to create a background color in InDesign // It only applies when the Underline property is set to true, and the UnderlineColor and UnderlineOffset are set as well. if ($underlineOn && $backColorName && $underlineOffset) { $declarationMgr = IdmlDeclarationManager::getInstance(); if (substr($backColorName, 0, 5) == 'Color') { $backColorValues = $declarationMgr->declaredColorHandler->declaredColors[$backColorName]; $backColor = IdmlDeclaredColors::rgbAsHex($backColorValues); $this->registerCSS('background-color', $backColor); } } }
/** * @return int */ public function getComputedBorders() { $w = $this->computedBorders; if ($w == 0) { $stylesMgr = IdmlDeclarationManager::getInstance(); // see if there are computed borders on any of the declared styles associated with this element foreach ($this->allStyles as $declaredStyle) { if (!array_key_exists($declaredStyle, $stylesMgr->declaredStyles)) { continue; } $w = $stylesMgr->declaredStyles[$declaredStyle]->computedBorders; if ($w != 0) { break; } } } return $w; }
public function convert() { // The Mode value must be 'Drop'; otherwise this isn't a drop shadow. if ($this->idmlPropertyValue == 'Drop') { // First, obtain the values of x-offset, y-offset, and color. // These are stored in separate properties in the contextual style $horizOffset = array_key_exists('ContentTransparencySetting::DropShadowSetting->XOffset', $this->idmlContext) ? $this->idmlContext['ContentTransparencySetting::DropShadowSetting->XOffset'] : '0'; $vertOffset = array_key_exists('ContentTransparencySetting::DropShadowSetting->YOffset', $this->idmlContext) ? $this->idmlContext['ContentTransparencySetting::DropShadowSetting->YOffset'] : '0'; $effectColor = array_key_exists('ContentTransparencySetting::DropShadowSetting->EffectColor', $this->idmlContext) ? $this->idmlContext['ContentTransparencySetting::DropShadowSetting->EffectColor'] : 'Color/Black'; $size = array_key_exists('ContentTransparencySetting::DropShadowSetting->Size', $this->idmlContext) ? $this->idmlContext['ContentTransparencySetting::DropShadowSetting->Size'] : '5'; // Convert the color from IDML syntax to rgb, using the color handler associated with the declaration manager $declarationMgr = IdmlDeclarationManager::getInstance(); $colorHandler = $declarationMgr->declaredColorHandler; $rgbColor = $colorHandler->colorRefAsHex($effectColor); // Use the components to assemble and register the CSS $propertyValue = sprintf('%spx %spx %spx %s', $horizOffset, $vertOffset, $size, $rgbColor); $this->registerCSS('text-shadow', $propertyValue); } }
public function convert() { $enableDropShadow = array_key_exists('TransparencySetting::DropShadowSetting->Mode', $this->idmlContext) ? $this->idmlContext['TransparencySetting::DropShadowSetting->Mode'] : 'None'; $enableInnerShadow = array_key_exists('TransparencySetting::InnerShadowSetting->Applied', $this->idmlContext) ? $this->idmlContext['TransparencySetting::InnerShadowSetting->Applied'] : 'false'; if ($enableDropShadow == 'None' && $enableInnerShadow == 'false') { return; } else { if ($enableDropShadow == 'Drop') { $inset = ''; } else { if ($enableInnerShadow == 'true') { $inset = 'inset'; } else { CakeLog::debug("[IdmlDecodeBoxShadow:convert] enableDropShadow={$enableDropShadow} enableInnerShadow={$enableInnerShadow}"); return; } } } // Initialize all values to defaults. Most may or may not be defined. $horizOffset = '7'; $vertOffset = '7'; $blur = '5'; $spread = 5; $opacity = 0.75; $rgb = array(0, 0, 0); // First, obtain the values of x- and y- offsets if (array_key_exists('TransparencySetting::DropShadowSetting->XOffset', $this->contextualStyle->idmlKeyValues)) { $horizOffset = (int) $this->contextualStyle->idmlKeyValues['TransparencySetting::DropShadowSetting->XOffset']; } if (array_key_exists('TransparencySetting::DropShadowSetting->YOffset', $this->contextualStyle->idmlKeyValues)) { $vertOffset = (int) $this->contextualStyle->idmlKeyValues['TransparencySetting::DropShadowSetting->YOffset']; } // Account for the 'angle' property of an inner shadow. // For now, we're simply assuming that if the angle is negative we have to reverse the 'polarity' by multiplying // the offsets by -1. IDML's strategy may be more complicated and may need further management. if (array_key_exists('TransparencySetting::InnerShadowSetting->Angle', $this->contextualStyle->idmlKeyValues)) { $angle = (int) $this->contextualStyle->idmlKeyValues['TransparencySetting::InnerShadowSetting->Angle']; if ($angle > 0) { $horizOffset *= -1; $vertOffset *= -1; } } // Next, obtain the values of size and color. if (array_key_exists('TransparencySetting::DropShadowSetting->Size', $this->contextualStyle->idmlKeyValues)) { $spread = $this->contextualStyle->idmlKeyValues['TransparencySetting::DropShadowSetting->Size']; } // Get CMYK color and convert to RGB array if (array_key_exists('TransparencySetting::DropShadowSetting->EffectColor', $this->contextualStyle->idmlKeyValues)) { $effectColor = $this->contextualStyle->idmlKeyValues['TransparencySetting::DropShadowSetting->EffectColor']; // Convert the color from IDML syntax to rgb, using the color handler associated with the declaration manager $declarationMgr = IdmlDeclarationManager::getInstance(); $colorHandler = $declarationMgr->declaredColorHandler; $rgb = $colorHandler->colorRefToRGB($effectColor); } // Idml's 'spread' is not the same as any CSS property. It affects the blur, but the size of the // shadow--including the blur--always remains inside the box specified by the size property (in CSS, blur pushes the // shadow outside the dimensions of its 'spread' property, which in CSS is the size of the shadow). Thus, the box shadow // models in IDML and CSS are fundamentally different. // Our use here is not correct, but rather represents a provisionary attempt at a best representation. // Blur is set based on spread: higher spread means lower blur, but the relationship is not linear, so use // a fractional exponent to scale. This still needs some tweaking, if not complete rewrite. if (array_key_exists('TransparencySetting::DropShadowSetting->Spread', $this->contextualStyle->idmlKeyValues)) { $idmlBlur = 100 - $this->contextualStyle->idmlKeyValues['TransparencySetting::DropShadowSetting->Spread']; $scalingExponent = 0.25; $blur = pow($idmlBlur, $scalingExponent); } // Add opacity to color $rgbColor = 'rgba(' . $rgb[0] . ',' . $rgb[1] . ',' . $rgb[2] . ',' . $opacity . ')'; // Use the components to assemble and register the CSS $propertyValue = $horizOffset . 'px ' . $vertOffset . 'px ' . $blur . 'px ' . $spread . 'px ' . $rgbColor . ' ' . $inset; $this->registerCSS('box-shadow', $propertyValue); }
/** * If the paragraph has a nested style, set up the necessary helper class object here */ private function parseNestedStyle() { $appliedParagraphStyleName = $this->appliedStyleName; $declarationMgr = IdmlDeclarationManager::getInstance(); $appliedParagraphStyle = $declarationMgr->declaredStyles[$appliedParagraphStyleName]; if (array_key_exists('Properties::AllNestedStyles', $appliedParagraphStyle->idmlKeyValues) && count($appliedParagraphStyle->idmlKeyValues['Properties::AllNestedStyles']) > 0) { $this->nestedStyleHelpers = array(); foreach ($appliedParagraphStyle->idmlKeyValues['Properties::AllNestedStyles'] as $nestedStyle) { $this->nestedStyleHelpers[] = new IdmlNestedStyleHelper($nestedStyle, $this); $this->hasNestedStyle = true; } } }
/** * @param string $cssTarget * @param string $colorRef * @param int $tint * @param int $weight */ public function convertFontStroke($cssTarget, $colorRef, $tint, $weight) { $handle = IdmlDeclarationManager::getInstance()->declaredColorHandler; list($colorRefType, $colorRefName) = explode('/', $colorRef, 2); switch ($colorRefType) { case 'Swatch': if ($colorRefName === 'None') { break; } case 'Color': case 'Ink': case 'MixedInk': case 'Tint': $rgbRaw = $handle->colorRefToRGB($colorRef); $rgbTint = $handle->applyTintToRGB($rgbRaw, $tint); $hexColor = $handle->rgbAsHex($rgbTint); $cssValue = sprintf('%spx %s', $weight, $hexColor); $this->registerCSS($cssTarget, $cssValue); } }
public function processBook() { $idmlAssembler = IdmlAssembler::getInstance(); $idmlAssembler->init($this); $idmlAssembler->addIDMLPackages($this->sourceFiles); $idmlAssembler->preparation(); $idmlAssembler->parse(); $idmlAssembler->produce(); // Saving the book CSS here is different from the original PXE implementation. // It clobbers the template.css for PXE created by the old (now obsolete) Style Manager. if (!$idmlAssembler->pxeTagsAdded) { $bookCss = IdmlDeclarationManager::getInstance()->convertIdmlToCSS(); $this->saveBookCSS($bookCss, 'template.css', false); } $idmlAssembler->adjustMaxSteps(); return true; }
/** * Populates the array of all the elements styles: contextual and applied. * @param IdmlElement $element */ private function setAllStyles(IdmlElement $element) { // Get applied styles. (IDML defaults the applied style name to 'n' if there is no applied style). if ($element->appliedStyleName != 'n') { $appliedStyle = $element->appliedStyleName; $declarationMgr = IdmlDeclarationManager::getInstance(); $appliedStyleKeys = $declarationMgr->declaredStyles[$appliedStyle]->idmlKeyValues; } else { $appliedStyleKeys = array(); } // Get contextual styles $contextualStyles = isset($element->contextualStyle->idmlKeyValues) ? $element->contextualStyle->idmlKeyValues : array(); // Merge the styles into a single array $this->allStyles = array_merge($appliedStyleKeys, $contextualStyles); }
/** * findProperty finds the most proximate defined value of the property $propName. * It first looks for an override value in the contextual style itself. * If not found, it then parses through the array of applied style class names to find a match. * * @param string $propName - the name of the style property we're looking for * @param array $styleList - An array of all applied styles, in application order. * @param string $fallback - value assigned to the property if it was not defined * @return string $propValue - The value of the property, either in a contextual style or an applied (class) style */ protected function findProperty($propName, $styleList, $fallback = '') { $propValue = $fallback; if (array_key_exists($propName, $this->idmlContext)) { // Value found in contextual style: return it return $this->idmlContext[$propName]; } $declarationMgr = IdmlDeclarationManager::getInstance(); // Go through the hierarchy of applied style classes to look for the property. foreach ($styleList as $style) { if (array_key_exists($style, $declarationMgr->declaredStyles)) { $appliedStyle = $declarationMgr->declaredStyles[$style]; if (array_key_exists($propName, $appliedStyle->idmlKeyValues)) { return $appliedStyle->idmlKeyValues[$propName]; } } } // If we reached here, return the value assigned as the fallback in the invocation return $propValue; }
/** * Get the TabList array property for the tab's containing paragraph. * If the tab list is not an array, or has no elements, it's not usable. * @return array|null */ protected function getTabLists() { $tabList = null; $paragraphStyles = $this->paragraph->contextualStyle->idmlKeyValues; if (array_key_exists('Properties::TabList', $paragraphStyles) && is_array($paragraphStyles['Properties::TabList']) && count($paragraphStyles['Properties::TabList']) > 0) { $tabList = $paragraphStyles['Properties::TabList']; } else { $declarationMgr = IdmlDeclarationManager::getInstance(); $paragraphStyles = $declarationMgr->declaredStyles[$this->paragraph->appliedStyleName]; if (is_array($paragraphStyles->idmlKeyValues['Properties::TabList'])) { $tabList = $paragraphStyles->idmlKeyValues['Properties::TabList']; } } return $tabList; }
public static function resetInstance() { IdmlDeclarationManager::$instance = null; }
/** * Initialize this instance. * * @param IdmlProcessor $processor * @return None */ public function init(IdmlProcessor $processor = null) { $this->processor = $processor; if ($processor) { $this->progressUpdater = ProgressUpdater::getInstance($processor->bookId); $this->FileManager = new FileManager($processor->bookId); $this->resourceManager = new IdmlResourceManager($processor, $this->FileManager); } else { $this->progressUpdater = null; $this->resourceManager = null; $this->FileManager = null; } $this->idmlPackages = array(); $this->styles = array(); $this->numPages = 0; $this->actualPages = 0; $this->pageProgression = 'left-to-right'; $this->facingPages = true; $this->currentIDMLFileIndex = 0; $this->currentIDMLPackageIndex = 0; //set this as default for unit testing purposes IdmlDeclarationManager::resetInstance(); }
/** The readDesignMap function obtains the filename pointers to the MasterSpreads, Resources, Spreads, * Stories, and XML from the designmap, which is the manifest that contains references to the names and locations * of the package's XML files. * * @return boolean true on success, false on failure. */ public function readDesignMap() { //first read the BackStory.xml file to see if any Stories, Hyperlinks, etc. should be ignored ... $this->readBackingStoryAndSetHiddenIds(); // The designmap contains references to everything in the package $designmap = $this->tempDir . '/designmap.xml'; if (!file_exists($designmap)) { $this->idmlAssembler->getProgressUpdater()->setWarning("{$designmap} does not exist."); return false; } // create DOMDocument and DOMXPath objects $doc = new DomDocument(); $b = $doc->load($designmap); if ($b === false) { return false; } $xpath = new DOMXPath($doc); // Parse the preferences file, which contains the width and height of our pages $tags = $xpath->query('//idPkg:Preferences'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->preferences = new IdmlPreferences(); $this->preferences->load($filename); IdmlAssembler::updateBookSize($this->preferences->pageWidth, $this->preferences->pageHeight); // The Declaration Manager deals with declared Colors, declared Styles, and declared Style Groups $manager = IdmlDeclarationManager::getInstance(); // Parse the graphics file which contains color declarations (this must be done before parsing the Styles) $tags = $xpath->query('//idPkg:Graphic'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $manager->loadDeclaredColors($filename); // There should always be exactly one Styles file *** Version 2: non-PEARSON *** $tags = $xpath->query('//idPkg:Styles'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $manager->loadDeclaredStyles($filename); /* // There should always be exactly one Styles file *** Version 1: PEARSON PXE *** $tags = $xpath->query('//idPkg:Styles'); assert( $tags->length == 1 ); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->style = new IdmlStyles($this); $this->style->filename = $filename; $this->style->load(); */ // Parse fonts file. $tags = $xpath->query('//idPkg:Fonts'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; IdmlFontManager::getInstance()->loadFonts($filename); // There should always be exactly one Tags file $tags = $xpath->query('//idPkg:Tags'); assert($tags->length == 1); $attr = $tags->item(0)->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $this->tags = new IdmlTags($this); $this->tags->filename = $filename; $this->tags->load(); // There are possibly several MasterSpread files, which are referenced by real spreads and accessed by their UID's. $tags = $xpath->query('//idPkg:MasterSpread'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $matches = null; $found = preg_match('|MasterSpreads/MasterSpread_(.*)\\.xml|', $attr->value, $matches); // u154 <-- MasterSpreads/MasterSpread_u154.xml if ($found == 1) { $UID = $matches[1]; $masterSpread = new IdmlMasterSpread($this); $masterSpread->filename = $filename; $this->masterSpreads[$UID] = $masterSpread; } else { $this->idmlAssembler->getProgressUpdater()->setWarning("Unable to determine UID for MasterSpread '{$attr->value}'."); } } // There are most likely many Spread files, and they are ordered in the designmap // according to the book's page ordering. $tags = $xpath->query('//idPkg:Spread'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $spread = new IdmlSpread($this); $spread->filename = $filename; $this->spreads[] = $spread; } // There are most likely many Story files, which are referenced by TextFrames and accessed by a parentStoryUID. $tags = $xpath->query('//idPkg:Story'); foreach ($tags as $tag) { $attr = $tag->attributes->getNamedItem('src'); $filename = "{$this->tempDir}/{$attr->value}"; $matches = null; $found = preg_match('|Stories/Story_(.*)\\.xml|', $attr->value, $matches); // u154 <-- Stories/Story_u154.xml if ($found == 1) { $UID = $matches[1]; if (!array_key_exists($UID, $this->chaucerHidden)) { //create/store the story if it is not hidden by a designer $story = new IdmlStory($UID); $story->filename = $filename; $this->stories[$UID] = $story; } } else { $this->idmlAssembler->getProgressUpdater()->setWarning("Unable to determine UID for Story '{$attr->value}'."); } } //Parse hyperlink information $this->hyperlinks = array(); $tags = $xpath->query('//Hyperlink'); $hyperlinkMgr = IdmlHyperlinkManager::getInstance(); foreach ($tags as $tag) { $properties = IdmlParserHelper::getAllDomNodeAttributesAndProperties($tag); // This code is (we think) PXE processing code if (!array_key_exists($properties['Self'], $this->chaucerHidden)) { // create/store the hyperlink if it is not hidden by a designer // The $destNode can be either a HyperlinkURLDestination or a HyperlinkPageDestination in the IDML, // and is referenced by the Hyperlink element. $destId = $properties['Destination']; $destNode = $xpath->query('//*[@Self="' . $destId . '"]'); if ($destNode->length > 0) { $destNode = $destNode->item(0); $properties['Destination'] = IdmlParserHelper::getAllDomNodeAttributesAndProperties($destNode); $properties['Destination']['DestinationType'] = $destNode->nodeName; } $this->hyperlinks[$properties['Self']] = $properties; } // The remainder of this foreach is specifically written for non-PXE IDML $hyperlinkSource = $properties['Source']; $external = false; // unless the link goes to a page outside the epub // If the Destination property is an array, the destination is a link to either // a page within the epub (with the page UID in the data), or or an external link. // So the destination can be set here. if (is_array($properties['Destination'])) { $anchor = false; // link is to a page, not an anchor if ($properties['Destination']['DestinationType'] == 'HyperlinkURLDestination') { // External page: use as is $hyperlinkDestination = $properties['Destination']['DestinationURL']; $external = true; // This links to a page outside the epub } else { // Internal page. Use the page UID; add the package index and the .html suffix $hyperlinkDestination = $properties['Destination']['DestinationPage']; } } else { $anchor = true; // link is to an anchor on a page. $hyperlinkDestination = 'Hyperlink_' . $properties['DestinationUniqueKey']; } $hyperlinkMgr->setSourceDestination($hyperlinkSource, $hyperlinkDestination, $anchor, $external); } //Parse layer information $layers = $xpath->query('//Layer'); $layerManager = IdmlLayerManager::getInstance(); foreach ($layers as $layer) { $layerManager->addLayer($layer); } return true; }
/** * @return string containing the canonical CSS classname applied to this element, * suitable for use in an HTML class='' attribute */ public function getCssClassname() { $idmlAppliedStyle = $this->appliedStyleName; if ($idmlAppliedStyle == '') { return ''; } $mgr = IdmlDeclarationManager::getInstance(); if (!array_key_exists($idmlAppliedStyle, $mgr->declaredStyles)) { return ''; } $declaredStyle = $mgr->declaredStyles[$idmlAppliedStyle]; // this will rarely happen, but might in the case of a <Change> element if (!$declaredStyle) { return ''; } // this is the normal case return $declaredStyle->getClassName(); }