public function register(Application $app)
 {
     $app['prince.path'] = null;
     // the common installation dirs for PrinceXML in several OS
     $app['prince.default_paths'] = array('/usr/local/bin/prince', '/usr/bin/prince', 'C:\\Program Files\\Prince\\engine\\bin\\prince.exe');
     $app['prince'] = $app->share(function () use($app) {
         $princePath = $app['prince.path'] ?: $app->findPrinceXmlExecutable();
         // ask the user about the location of the executable
         if (null == $princePath) {
             $princePath = $app->askForPrinceXMLExecutablePath();
             if (!file_exists($princePath)) {
                 throw new \RuntimeException(sprintf("We couldn't find the PrinceXML executable in the given directory (%s)", $princePath));
             }
         }
         $prince = new Prince($princePath);
         $prince->setHtml(true);
         return $prince;
     });
 }
Exemple #2
0
 public function __construct()
 {
     $app = $this;
     // -- global generic parameters ---------------------------------------
     $this['app.debug'] = true;
     $this['app.charset'] = 'UTF-8';
     $this['app.name'] = 'easybook';
     $this['app.version'] = '4.4';
     $this['app.signature'] = "\n" . "                     |              |    \n" . " ,---.,---.,---.,   .|---.,---.,---.|__/ \n" . " |---',---|`---.|   ||   ||   ||   ||  \\ \n" . " `---'`---^`---'`---|`---'`---'`---'`   `\n" . "                `---'\n";
     // -- global directories location -------------------------------------
     $this['app.dir.base'] = realpath(__DIR__ . '/../../../');
     $this['app.dir.cache'] = $this['app.dir.base'] . '/app/Cache';
     $this['app.dir.doc'] = $this['app.dir.base'] . '/doc';
     $this['app.dir.resources'] = $this['app.dir.base'] . '/app/Resources';
     $this['app.dir.plugins'] = $this['app.dir.base'] . '/src/Easybook/Plugins';
     $this['app.dir.translations'] = $this['app.dir.resources'] . '/Translations';
     $this['app.dir.skeletons'] = $this['app.dir.resources'] . '/Skeletons';
     $this['app.dir.themes'] = $this['app.dir.resources'] . '/Themes';
     // -- default edition options -----------------------------------------
     // TODO: each edition type should define different values
     $this['app.edition.defaults'] = array('format' => 'html', 'highlight_code' => false, 'include_styles' => true, 'isbn' => null, 'labels' => array('appendix', 'chapter', 'figure'), 'margin' => array('top' => '25mm', 'bottom' => '25mm', 'inner' => '30mm', 'outter' => '20mm'), 'page_size' => 'A4', 'theme' => 'clean', 'toc' => array('deep' => 2, 'elements' => array('appendix', 'chapter')), 'two_sided' => true);
     // -- timer -----------------------------------------------------------
     $this['app.timer.start'] = 0.0;
     $this['app.timer.finish'] = 0.0;
     // -- publishing process variables ------------------------------------
     // holds the app theme dir for the current edition
     $this['publishing.dir.app_theme'] = '';
     $this['publishing.dir.book'] = '';
     $this['publishing.dir.contents'] = '';
     $this['publishing.dir.resources'] = '';
     $this['publishing.dir.plugins'] = '';
     $this['publishing.dir.templates'] = '';
     $this['publishing.dir.output'] = '';
     $this['publishing.edition'] = '';
     $this['publishing.items'] = array();
     // the specific item currently being parsed/modified/decorated/...
     $this['publishing.active_item'] = array();
     $this['publishing.book.slug'] = '';
     $this['publishing.book.items'] = array();
     // holds all the generated slugs, to avoid repetitions
     $this['publishing.slugs'] = array();
     // holds all the internal links (used in html_chunked and epub editions)
     $this['publishing.links'] = array();
     $this['publishing.list.images'] = array();
     $this['publishing.list.tables'] = array();
     $this['publishing.id'] = $this->share(function ($app) {
         if (null != ($isbn = $app->edition('isbn'))) {
             return array('scheme' => 'isbn', 'value' => $isbn);
         }
         // if the book doesn't declare an ISBN, generate
         // a unique ID based on RFC 4211 UUID v4
         return array('scheme' => 'URN', 'value' => Toolkit::uuid());
     });
     // -- event dispatcher ------------------------------------------------
     $this['dispatcher'] = $this->share(function () {
         return new EventDispatcher();
     });
     // -- finder ----------------------------------------------------------
     $this['finder'] = function () {
         return new Finder();
     };
     // -- filesystem ------------------------------------------------------
     $this['filesystem'] = $this->share(function ($app) {
         return new Filesystem();
     });
     // -- publisher -------------------------------------------------------
     $this['publisher'] = $this->share(function ($app) {
         $outputFormat = $app->edition('format');
         switch (strtolower($outputFormat)) {
             case 'pdf':
                 return new PdfPublisher($app);
             case 'html':
                 return new HtmlPublisher($app);
             case 'html_chunked':
                 return new HtmlChunkedPublisher($app);
             case 'epub':
             case 'epub2':
                 return new Epub2Publisher($app);
                 //case 'epub3':
                 //    return new Epub3Publisher($app);
             //case 'epub3':
             //    return new Epub3Publisher($app);
             default:
                 throw new \Exception(sprintf('Unknown "%s" format for "%s" edition (allowed: "pdf", "html", "html_chunked", "epub", "epub2")', $outputFormat, $app->get('publishing.edition')));
         }
     });
     // -- parser ----------------------------------------------------------
     $this['parser'] = $this->share(function ($app) {
         $format = strtolower($app['publishing.active_item']['config']['format']);
         // TODO: extensibility -> support several format parsers (RST, Textile, ...)
         switch ($format) {
             case 'md':
             case 'mdown':
             case 'markdown':
                 return new MdParser($app);
             default:
                 throw new \Exception(sprintf('Unknown "%s" format for "%s" content (easybook only supports Markdown)', $format, $app['publishing.active_item']['config']['content']));
         }
     });
     // -- twig ------------------------------------------------------------
     $this['twig.options'] = array('autoescape' => false, 'charset' => $this['app.charset'], 'debug' => $this['app.debug'], 'strict_variables' => $this['app.debug']);
     // the twig path used by render() function. This value is set by convenience methods
     // (renderCustomTemplate(), renderThemeTemplate(), ...) before template rendering
     $this['twig.path'] = '';
     // twig path for custom templates (user defined templates for book/edition)
     $this['twig.path.custom'] = $this->share(function ($app) {
         $paths = array();
         // edition custom templates
         // <book-dir>/Resources/Templates/<edition-name>/<template-name>.twig
         $dir = $app['publishing.dir.templates'] . '/' . $app['publishing.edition'];
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         // edition type custom templates (epub, pdf, html, html_chunked)
         // <book-dir>/Resources/Templates/<edition-type>/<template-name>.twig
         $dir = $app['publishing.dir.templates'] . '/' . $app->edition('format');
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         // book custom templates (same templates for all editions)
         // <book-dir>/Resources/Templates/<template-name>.twig
         $dir = $app['publishing.dir.templates'];
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         return $paths;
     });
     // twig path for default theme templates (easybook built-in templates)
     $this['twig.path.theme'] = $this->share(function ($app) {
         $paths = array();
         $theme = ucfirst($app->edition('theme'));
         $format = Toolkit::camelize($app->edition('format'), true);
         // TODO: fix the following hack
         if ('Epub' == $format) {
             $format = 'Epub2';
         }
         // default templates for the edition/book theme
         // <easybook>/app/Resources/Themes/<theme>/<edition-type>/Templates/<template-name>.twig
         $dir = sprintf('%s/%s/%s/Templates', $app['app.dir.themes'], $theme, $format);
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         // default common templates for all the editions of the same theme
         // <easybook>/app/Resources/Themes/<theme>/Common/Templates/<template-name>.twig
         $dir = sprintf('%s/%s/Common/Templates', $app['app.dir.themes'], $theme);
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         // default base theme for every edition and every book
         // <easybook>/app/Resources/Themes/Base/<edition-type>/Templates/<template-name>.twig
         $dir = sprintf('%s/Base/%s/Templates', $app['app.dir.themes'], $format);
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         return $paths;
     });
     // twig path for default content templates
     // (easybook built-in templates for contents; e.g. `license.md.twig`)
     $this['twig.path.contents'] = $this->share(function ($app) {
         $paths = array();
         $theme = ucfirst($app->edition('theme'));
         $format = Toolkit::camelize($app->edition('format'), true);
         // TODO: fix the following hack
         if ('Epub' == $format) {
             $format = 'Epub2';
         }
         // default content templates for the edition/book theme
         // <easybook>/app/Resources/Themes/<theme>/<edition-type>/Contents/<template-name>.twig
         $dir = sprintf('%s/%s/%s/Contents', $app['app.dir.themes'], $theme, $format);
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         // default content templates for every edition and every book
         // <easybook>/app/Resources/Themes/Base/<edition-type>/Contents/<template-name>.twig
         $dir = sprintf('%s/Base/%s/Contents', $app['app.dir.themes'], $format);
         if (file_exists($dir)) {
             $paths[] = $dir;
         }
         return $paths;
     });
     $this['twig.loader'] = function () use($app) {
         return new \Twig_Loader_Filesystem($app['twig.path']);
     };
     $this['twig'] = function () use($app) {
         $twig = new \Twig_Environment($app['twig.loader'], $app['twig.options']);
         $twig->addExtension(new TwigCssExtension());
         $twig->addGlobal('app', $app);
         if (null != $app->get('book')) {
             $twig->addGlobal('book', $app->get('book'));
             $publishingEdition = $app->get('publishing.edition');
             $editions = $app->book('editions');
             $twig->addGlobal('edition', $editions[$publishingEdition]);
         }
         return $twig;
     };
     // -- princeXML -------------------------------------------------------
     $this['prince.default_paths'] = array('/usr/local/bin/prince', '/usr/bin/prince', 'C:\\Program Files\\Prince\\engine\\bin\\prince.exe');
     $this['prince'] = $app->share(function () use($app) {
         // look for the executable file of PrinceXML
         $princePath = null;
         foreach ($app['prince.default_paths'] as $path) {
             if (file_exists($path)) {
                 $princePath = $path;
                 break;
             }
         }
         if (null == $princePath) {
             echo sprintf(" In order to generate PDF files, PrinceXML library must be installed. \n\n" . " We couldn't find PrinceXML executable in any of the following directories: \n" . "   -> %s \n\n" . " If you haven't installed it yet, you can download a fully-functional demo at: \n" . " %s \n\n" . " If you have installed in a custom directory, please type its full absolute path:\n > ", implode($app['prince.default_paths'], "\n   -> "), 'http://www.princexml.com/download');
             $input = trim(fgets(STDIN));
             if (file_exists($input)) {
                 $princePath = $input;
                 echo "\n";
             } else {
                 throw new \Exception(sprintf("We couldn't find the PrinceXML executable in the given directory (%s)", $input));
             }
         }
         $prince = new Prince($princePath);
         $prince->setHtml(true);
         return $prince;
     });
     // -- slugger ---------------------------------------------------------
     $this['slugger'] = $app->share(function () use($app) {
         return new Slugger($app);
     });
     // -- code syntax highlighter -----------------------------------------
     $this['geshi'] = function () use($app) {
         require_once __DIR__ . '/../../../vendor/geshi/geshi/geshi.php';
         $geshi = new \GeSHi();
         $geshi->enable_classes();
         // this must be the first method (see Geshi doc)
         $geshi->set_encoding($app['app.charset']);
         $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS);
         $geshi->enable_keyword_links(false);
         return $geshi;
     };
     // -- labels ---------------------------------------------------------
     $this['labels'] = $app->share(function () use($app) {
         $labels = Yaml::parse($app['app.dir.translations'] . '/labels.' . $app->book('language') . '.yml');
         // books can define their own labels files
         if (null != ($customLabelsFile = $app->getCustomLabelsFile())) {
             $customLabels = Yaml::parse($customLabelsFile);
             return Toolkit::array_deep_merge($labels, $customLabels);
         }
         return $labels;
     });
     // -- titles ----------------------------------------------------------
     $this['titles'] = $app->share(function () use($app) {
         $titles = Yaml::parse($app['app.dir.translations'] . '/titles.' . $app->book('language') . '.yml');
         // books can define their own titles files
         if (null != ($customTitlesFile = $app->getCustomTitlesFile())) {
             $customTitles = Yaml::parse($customTitlesFile);
             return Toolkit::array_deep_merge($titles, $customTitles);
         }
         return $titles;
     });
 }