Example #1
0
 private function createNavPoint(\DOMDocument $document, ManifestItem $item, &$index)
 {
     $child = $document->createElement('navPoint');
     $child->setAttribute('id', sprintf('navpoint-%d', $index));
     $child->setAttribute('playOrder', $index);
     $dom = new \DOMDocument('1.0');
     @$dom->loadHTML($item->getContent());
     $title = $dom->getElementsByTagName('title')->item(0);
     if (!$title) {
         $title = basename($item->href, '.html');
     } else {
         $title = $title->nodeValue;
     }
     $label = $document->createElement('navLabel');
     $text = $document->createElement('text', $title);
     $label->appendChild($text);
     $child->appendChild($label);
     $content = $document->createElement('content');
     $content->setAttribute('src', $item->href);
     $child->appendChild($content);
     $xpath = new \DOMXPath($dom);
     $headers = $xpath->query('//h3/a[@id]');
     $createNavPoint = function ($id, $class, $title, $src, $playOrder) use($document) {
         $child = $document->createElement('navPoint');
         $child->setAttribute('id', $id);
         $child->setAttribute('class', $class);
         $child->setAttribute('playOrder', $playOrder);
         $label = $document->createElement('navLabel');
         $text = $document->createElement('text', $title);
         $label->appendChild($text);
         $child->appendChild($label);
         $content = $document->createElement('content');
         $content->setAttribute('src', $src);
         $child->appendChild($content);
         return $child;
     };
     if ($headers) {
         foreach ($headers as $node) {
             // only add 2nd level headers
             if (!preg_match('/^\\d+\\.\\d+$/', $node->nodeValue)) {
                 continue;
             }
             $ref = $node->getAttribute('id');
             $title = $node->nextSibling->nodeValue;
             $child->appendChild($createNavPoint(str_replace('.', '_', $ref), 'h2', $title, sprintf('%s#%s', $item->href, $ref), ++$index));
         }
     }
     return $child;
 }
Example #2
0
    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $destination = $input->getArgument('output');
        // use realpath because we need the absolute location
        $filename = realpath(dirname($destination)) . '/' . basename($destination);
        $workingDir = sys_get_temp_dir() . uniqid('build-epub-');
        mkdir($workingDir);
        $converter = new Txt2HtmlConverter(realpath($input->getArgument('input')), $workingDir);
        $converter->convert();
        $sourceFiles = $converter->getFiles();
        $this->workingDir = $workingDir;
        $package = new Package();
        $metadata = array('title' => 'HTTP Protocol', 'identifier' => 'http-protocol', 'language' => 'en');
        foreach ($metadata as $name => $value) {
            $item = new MetadataItem();
            $item->name = $name;
            $item->value = $value;
            $package->metadata->add($item);
        }
        $toc = new ManifestItem();
        $toc->type = 'application/x-dtbncx+xml';
        $toc->href = 'toc.ncx';
        $toc->id = 'ncx';
        $toc->setContent(function () use($package) {
            $dumper = new TocResourceDumper($package);
            return $dumper->dump();
        });
        $package->manifest->add($toc);
        foreach ($sourceFiles as $name => $file) {
            $item = new ManifestItem();
            $item->href = $name;
            // fix the filenames for sorting purposes
            if (preg_match('/rfc(\\d+)-sec(\\d+)\\.html/', $item->href, $match)) {
                $item->href = sprintf('x-rfc%s-sec%04s.html', $match[1], $match[2]);
            }
            $item->type = 'application/xhtml+xml';
            $item->id = basename($item->href, '.html');
            $item->setContent($this->repairSpecHTML(file_get_contents($file)));
            unlink($file);
            $package->manifest->add($item);
            $package->spine->add($item);
        }
        $this->addFromString('mimetype', 'application/epub+zip');
        $this->addFromString('META-INF/container.xml', <<<EOT
<?xml version="1.0"?>
<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
   <rootfiles>
      <rootfile full-path="content.opf" media-type="application/oebps-package+xml"/>
   </rootfiles>
</container>
EOT
);
        $dumper = new OpfResourceDumper($package);
        $this->addFromString('content.opf', $dumper->dump());
        foreach ($package->manifest->all() as $item) {
            $this->addFromString($item->href, $item->getContent());
        }
        exec(sprintf('(cd %s && zip -q0Xj %s %s)', escapeshellarg($workingDir), escapeshellarg($filename), 'mimetype'));
        exec(sprintf('(cd %s && zip -Xur9D %s *)', escapeshellarg($workingDir), escapeshellarg($filename)));
        exec(sprintf('rm -rf %s', escapeshellarg($workingDir)));
    }