PageRenderTime 103ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 1ms

/phd/phpdotnet/phd/BuildOptionsParser.php

https://bitbucket.org/solarphp/docs
PHP | 463 lines | 417 code | 32 blank | 14 comment | 51 complexity | 93210e6aa6c949b84fc41c522ffaf37a MD5 | raw file
Possible License(s): IPL-1.0, LGPL-2.0, Apache-2.0, 0BSD
  1. <?php
  2. namespace phpdotnet\phd;
  3. /* $Id: BuildOptionsParser.php 300140 2010-06-03 03:33:21Z philip $ */
  4. class BuildOptionsParser
  5. {
  6. public function __construct()
  7. {
  8. // By default, Windows does not support colors on the console.
  9. // ANSICON by Jason Hood can be used to provide colors at the console.
  10. // Color output can still be set via the command line parameters.
  11. if('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
  12. $this->option_color('color', 'off');
  13. }
  14. }
  15. public function getOptionList()
  16. {
  17. return array(
  18. 'format:' => 'f:', // The format to render (xhtml, pdf...)
  19. 'noindex' => 'I', // Do not re-index
  20. 'forceindex' => 'r', // Force re-indexing under all circumstances
  21. 'notoc' => 't', // Do not re-create TOC
  22. 'docbook:' => 'd:', // The Docbook XML file to render from (.manual.xml)
  23. 'output:' => 'o:', // The output directory
  24. 'partial:' => 'p:', // The ID to render (optionally ignoring its children)
  25. 'skip:' => 's:', // The ID to skip (optionally skipping its children too)
  26. 'verbose:' => 'v::', // Adjust the verbosity level
  27. 'list' => 'l', // List supported packages/formats
  28. 'lang::' => 'L:', // Language hint (used by the CHM)
  29. 'color:' => 'c:', // Use color output if possible
  30. 'highlighter:' => 'g:', // Class used as source code highlighter
  31. 'version' => 'V', // Print out version information
  32. 'help' => 'h', // Print out help
  33. 'package:' => 'P:', // The package of formats
  34. 'css:' => 'C:', // External CSS
  35. 'xinclude' => 'x', // Automatically process xinclude directives
  36. 'ext:' => 'e:', // The file-format extension to use, including the dot
  37. 'saveconfig::' => 'S::', // Save the generated config ?
  38. );
  39. }
  40. public function option_f($k, $v)
  41. {
  42. $this->option_format($k, $v);
  43. }
  44. public function option_format($k, $v)
  45. {
  46. $formats = array();
  47. foreach((array)$v as $i => $val) {
  48. if (!in_array($val, $formats)) {
  49. $formats[] = $val;
  50. }
  51. }
  52. Config::set_output_format($formats);
  53. }
  54. public function option_e($k, $v)
  55. {
  56. $this->option_ext($k, $v);
  57. }
  58. public function option_ext($k, $v)
  59. {
  60. $bool = self::boolval($v);
  61. if ($bool === false) {
  62. // `--ext=false` means no extension will be used
  63. $v = "";
  64. Config::setExt($v);
  65. } elseif ($bool === null) {
  66. // `--ext=true` means use the default extension,
  67. // `--ext=".foo"` means use ".foo" as the extension
  68. Config::setExt($v);
  69. }
  70. }
  71. public function option_g($k, $v)
  72. {
  73. $this->option_highlighter($k, $v);
  74. }
  75. public function option_highlighter($k, $v)
  76. {
  77. Config::setHighlighter($v);
  78. }
  79. public function option_i($k, $v)
  80. {
  81. $this->option_noindex($k, 'true');
  82. }
  83. public function option_noindex($k, $v)
  84. {
  85. Config::set_no_index(true);
  86. }
  87. public function option_r($k, $v)
  88. {
  89. $this->option_forceindex($k, 'true');
  90. }
  91. public function option_forceindex($k, $v)
  92. {
  93. Config::set_force_index(true);
  94. }
  95. public function option_t($k, $v)
  96. {
  97. $this->option_notoc($k, 'true');
  98. }
  99. public function option_notoc($k, $v)
  100. {
  101. Config::set_no_toc(true);
  102. }
  103. public function option_d($k, $v)
  104. {
  105. $this->option_docbook($k, $v);
  106. }
  107. public function option_docbook($k, $v)
  108. {
  109. if (is_array($v)) {
  110. trigger_error("Can only parse one file at a time", E_USER_ERROR);
  111. }
  112. if (!file_exists($v) || is_dir($v) || !is_readable($v)) {
  113. trigger_error(sprintf("'%s' is not a readable docbook file", $v), E_USER_ERROR);
  114. }
  115. Config::set_xml_root(dirname($v));
  116. Config::set_xml_file($v);
  117. }
  118. public function option_o($k, $v)
  119. {
  120. $this->option_output($k, $v);
  121. }
  122. public function option_output($k, $v)
  123. {
  124. if (is_array($v)) {
  125. trigger_error("Only a single output location can be supplied", E_USER_ERROR);
  126. }
  127. @mkdir($v, 0777, true);
  128. if (!is_dir($v) || !is_readable($v)) {
  129. trigger_error(sprintf("'%s' is not a valid directory", $v), E_USER_ERROR);
  130. }
  131. $v = (substr($v, strlen($v) - strlen(DIRECTORY_SEPARATOR)) == DIRECTORY_SEPARATOR) ? $v : ($v . DIRECTORY_SEPARATOR);
  132. Config::set_output_dir($v);
  133. }
  134. public function option_p($k, $v)
  135. {
  136. if ($k == "P") {
  137. return $this->option_package($k, $v);
  138. }
  139. $this->option_partial($k, $v);
  140. }
  141. public function option_partial($k, $v)
  142. {
  143. $render_ids = Config::render_ids();
  144. foreach((array)$v as $i => $val) {
  145. $recursive = true;
  146. if (strpos($val, "=") !== false) {
  147. list($val, $recursive) = explode("=", $val);
  148. if (!is_numeric($recursive) && defined($recursive)) {
  149. $recursive = constant($recursive);
  150. }
  151. $recursive = (bool) $recursive;
  152. }
  153. $render_ids[$val] = $recursive;
  154. }
  155. Config::set_render_ids($render_ids);
  156. }
  157. public function option_package($k, $v) {
  158. foreach((array)$v as $package) {
  159. if (!in_array($package, Config::getSupportedPackages())) {
  160. $supported = implode(', ', Config::getSupportedPackages());
  161. trigger_error("Invalid Package (Tried: '$package' Supported: '$supported')", E_USER_ERROR);
  162. }
  163. }
  164. Config::set_package($v);
  165. }
  166. public function option_s($k, $v)
  167. {
  168. if ($k == "S") {
  169. return $this->option_saveconfig($k, $v);
  170. }
  171. $this->option_skip($k, $v);
  172. }
  173. public function option_skip($k, $v)
  174. {
  175. $skip_ids = Config::skip_ids();
  176. foreach((array)$v as $i => $val) {
  177. $recursive = true;
  178. if (strpos($val, "=") !== false) {
  179. list($val, $recursive) = explode("=", $val);
  180. if (!is_numeric($recursive) && defined($recursive)) {
  181. $recursive = constant($recursive);
  182. }
  183. $recursive = (bool) $recursive;
  184. }
  185. $skip_ids[$val] = $recursive;
  186. }
  187. Config::set_skip_ids($skip_ids);
  188. }
  189. public function option_saveconfig($k, $v)
  190. {
  191. if (is_array($v)) {
  192. trigger_error(sprintf("You cannot pass %s more than once", $k), E_USER_ERROR);
  193. }
  194. // No arguments passed, default to 'true'
  195. if (is_bool($v)) {
  196. $v = "true";
  197. }
  198. $val = self::boolval($v);
  199. if (is_bool($val)) {
  200. Config::set_saveconfig($v);
  201. } else {
  202. trigger_error("yes/no || on/off || true/false || 1/0 expected", E_USER_ERROR);
  203. }
  204. }
  205. public function option_v($k, $v)
  206. {
  207. if ($k[0] === 'V') {
  208. $this->option_version($k, $v);
  209. return;
  210. }
  211. $this->option_verbose($k, $v);
  212. }
  213. public function option_verbose($k, $v)
  214. {
  215. static $verbose = 0;
  216. foreach((array)$v as $i => $val) {
  217. foreach(explode("|", $val) as $const) {
  218. if (defined($const)) {
  219. $verbose |= (int)constant($const);
  220. } elseif (is_numeric($const)) {
  221. $verbose |= (int)$const;
  222. } elseif (empty($const)) {
  223. $verbose = max($verbose, 1);
  224. $verbose <<= 1;
  225. } else {
  226. trigger_error("Unknown option passed to --$k, '$const'", E_USER_ERROR);
  227. }
  228. }
  229. }
  230. Config::set_verbose($verbose);
  231. error_reporting($GLOBALS['olderrrep'] | $verbose);
  232. }
  233. public function option_l($k, $v)
  234. {
  235. if ($k == "L") {
  236. return $this->option_lang($k, $v);
  237. }
  238. $this->option_list($k, $v);
  239. }
  240. public function option_list($k, $v)
  241. {
  242. $packageList = Config::getSupportedPackages();
  243. echo "Supported packages:\n";
  244. foreach ($packageList as $package) {
  245. $formats = Format_Factory::createFactory($package)->getOutputFormats();
  246. echo "\t" . $package . "\n\t\t" . implode("\n\t\t", $formats) . "\n";
  247. }
  248. exit(0);
  249. }
  250. public function option_lang($k, $v)
  251. {
  252. Config::set_language($v);
  253. }
  254. public function option_c($k, $v)
  255. {
  256. if ($k == "C") {
  257. return $this->option_css($k, $v);
  258. }
  259. $this->option_color($k, $v);
  260. }
  261. public function option_color($k, $v)
  262. {
  263. if (is_array($v)) {
  264. trigger_error(sprintf("You cannot pass %s more than once", $k), E_USER_ERROR);
  265. }
  266. $val = self::boolval($v);
  267. if (is_bool($val)) {
  268. Config::setColor_output($val);
  269. } else {
  270. trigger_error("yes/no || on/off || true/false || 1/0 expected", E_USER_ERROR);
  271. }
  272. }
  273. public function option_css($k, $v) {
  274. $styles = array();
  275. foreach((array)$v as $key => $val) {
  276. if (!in_array($val, $styles)) {
  277. $styles[] = $val;
  278. }
  279. }
  280. Config::set_css($styles);
  281. }
  282. public function option_x($k, $v)
  283. {
  284. $this->option_xinclude($k, 'true');
  285. }
  286. public function option_xinclude($k, $v)
  287. {
  288. Config::set_process_xincludes(true);
  289. }
  290. /**
  291. * Prints out the current PhD and PHP version.
  292. * Exits directly.
  293. *
  294. * @return void
  295. */
  296. public function option_version($k, $v)
  297. {
  298. $color = Config::phd_info_color();
  299. $output = Config::phd_info_output();
  300. fprintf($output, "%s\n", term_color('PhD Version: ' . Config::VERSION, $color));
  301. fprintf($output, "%s\n", term_color('PHP Version: ' . phpversion(), $color));
  302. fprintf($output, "%s\n", term_color('Copyright(c) 2007-2010 The PHP Documentation Group', $color));
  303. exit(0);
  304. }
  305. public function option_h($k, $v)
  306. {
  307. $this->option_help($k, $v);
  308. }
  309. public function option_help($k, $v)
  310. {
  311. echo "PhD version: " .Config::VERSION;
  312. echo "\nCopyright (c) 2007-2010 The PHP Documentation Group\n
  313. -v
  314. --verbose <int> Adjusts the verbosity level
  315. -f <formatname>
  316. --format <formatname> The build format to use
  317. -P <packagename>
  318. --package <packagename> The package to use
  319. -I
  320. --noindex Do not index before rendering but load from cache
  321. (default: false)
  322. -r
  323. --forceindex Force re-indexing under all circumstances
  324. (default: false)
  325. -t
  326. --notoc Do not rewrite TOC before rendering but load from cache
  327. (default: false)
  328. -d <filename>
  329. --docbook <filename> The Docbook file to render from
  330. -x
  331. --xinclude Process XML Inclusions (XInclude)
  332. (default: false)
  333. -p <id[=bool]>
  334. --partial <id[=bool]> The ID to render, optionally skipping its children
  335. chunks (default to true; render children)
  336. -s <id[=bool]>
  337. --skip <id[=bool]> The ID to skip, optionally skipping its children
  338. chunks (default to true; skip children)
  339. -l
  340. --list Print out the supported packages and formats
  341. -o <directory>
  342. --output <directory> The output directory (default: .)
  343. -L <language>
  344. --lang <language> The language of the source file (used by the CHM
  345. theme). (default: en)
  346. -c <bool>
  347. --color <bool> Enable color output when output is to a terminal
  348. (default: true; On Windows the default is false)
  349. -C <filename>
  350. --css <filename> Link for an external CSS file.
  351. -g <classname>
  352. --highlighter <classname> Use custom source code highlighting php class
  353. -V
  354. --version Print the PhD version information
  355. -h
  356. --help This help
  357. -e <extension>
  358. --ext <extension> The alternative filename extension to use, including
  359. the dot. Use 'false' for no extension.
  360. -S <bool>
  361. --saveconfig <bool> Save the generated config (default: false).
  362. Most options can be passed multiple times for greater effect.
  363. ";
  364. exit(0);
  365. }
  366. public function handlerForOption($opt)
  367. {
  368. if (method_exists($this, "option_{$opt}")) {
  369. return array($this, "option_{$opt}");
  370. } else {
  371. return NULL;
  372. }
  373. }
  374. public static function getopt()
  375. {
  376. $bop = new self;
  377. $opts = $bop->getOptionList();
  378. $args = getopt(implode('', array_values($opts)), array_keys($opts));
  379. if ($args === false) {
  380. trigger_error("Something happend with getopt(), please report a bug", E_USER_ERROR);
  381. }
  382. foreach ($args as $k => $v) {
  383. $handler = $bop->handlerForOption($k);
  384. if (is_callable($handler)) {
  385. call_user_func($handler, $k, $v);
  386. } else {
  387. var_dump($k, $v);
  388. trigger_error("Hmh, something weird has happend, I don't know this option", E_USER_ERROR);
  389. }
  390. }
  391. }
  392. /**
  393. * Makes a string into a boolean (i.e. on/off, yes/no, ..)
  394. *
  395. * Returns boolean true/false on success, null on failure
  396. *
  397. * @param string $val
  398. * @return bool
  399. */
  400. public static function boolval($val) {
  401. if (!is_string($val)) {
  402. return null;
  403. }
  404. switch ($val) {
  405. case "on":
  406. case "yes":
  407. case "true":
  408. case "1":
  409. return true;
  410. break;
  411. case "off":
  412. case "no":
  413. case "false":
  414. case "0":
  415. return false;
  416. break;
  417. default:
  418. return null;
  419. }
  420. }
  421. }
  422. /*
  423. * vim600: sw=4 ts=4 syntax=php et
  424. * vim<600: sw=4 ts=4
  425. */