PageRenderTime 58ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/solar/1.1.1/source/solar/Solar/Cli/MakeDocbook.php

http://github.com/pmjones/php-framework-benchmarks
PHP | 572 lines | 176 code | 36 blank | 360 comment | 13 complexity | bf9d767e6a29dbc49de118ef9f908914 MD5 | raw file
Possible License(s): LGPL-3.0, Apache-2.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1
  1. <?php
  2. /**
  3. *
  4. * Generates package and API documentation files.
  5. *
  6. * @category Solar
  7. *
  8. * @package Solar_Cli
  9. *
  10. * @subpackage Solar_Cli_MakeDocbook
  11. *
  12. * @author Paul M. Jones <pmjones@solarphp.com>
  13. *
  14. * @license http://opensource.org/licenses/bsd-license.php BSD
  15. *
  16. * @version $Id: MakeDocbook.php 4611 2010-06-19 09:13:31Z pmjones $
  17. *
  18. */
  19. class Solar_Cli_MakeDocbook extends Solar_Controller_Command
  20. {
  21. /**
  22. *
  23. * Default configuration values.
  24. *
  25. * @config string class_dir The directory in which wiki-based class docs
  26. * are stored.
  27. *
  28. * @config string package_dir The directory in which wiki-based package
  29. * docs are stored.
  30. *
  31. * @config string docbook_dir The directory in which to save DocBook
  32. * files.
  33. *
  34. * @var array
  35. *
  36. */
  37. protected $_Solar_Cli_MakeDocbook = array(
  38. 'class_dir' => null,
  39. 'package_dir' => null,
  40. 'docbook_dir' => null,
  41. );
  42. /**
  43. *
  44. * Read class API source files from this directory.
  45. *
  46. * @var string
  47. *
  48. */
  49. protected $_class_dir;
  50. /**
  51. *
  52. * Read package source files from this directory.
  53. *
  54. * @var string
  55. *
  56. */
  57. protected $_package_dir;
  58. /**
  59. *
  60. * Write docbook files to this directory.
  61. *
  62. * @var string
  63. *
  64. */
  65. protected $_docbook_dir;
  66. /**
  67. *
  68. * A Solar_Markdown object for converting wiki docs to DocBook.
  69. *
  70. * @var Solar_Markdown_Apidoc
  71. *
  72. */
  73. protected $_markdown;
  74. /**
  75. *
  76. * An array of DocBook template files.
  77. *
  78. * @var array
  79. *
  80. */
  81. protected $_templates;
  82. /**
  83. *
  84. * Post-construction tasks to complete object construction.
  85. *
  86. * @return void
  87. *
  88. */
  89. protected function _postConstruct()
  90. {
  91. parent::_postConstruct();
  92. if ($this->_config['class_dir']) {
  93. $this->_class_dir = Solar_Dir::fix($this->_config['class_dir']);
  94. }
  95. if ($this->_config['package_dir']) {
  96. $this->_package_dir = Solar_Dir::fix($this->_config['package_dir']);
  97. }
  98. if ($this->_config['docbook_dir']) {
  99. $this->_docbook_dir = Solar_Dir::fix($this->_config['docbook_dir']);
  100. }
  101. $this->_markdown = Solar::factory('Solar_Markdown_Apidoc');
  102. }
  103. /**
  104. *
  105. * Main action: parse the classes and write documentation.
  106. *
  107. * @param string $vendor Parse for this vendor name.
  108. *
  109. * @return void
  110. *
  111. */
  112. protected function _exec($vendor = null)
  113. {
  114. $begin = time();
  115. if (! $vendor) {
  116. $vendor = 'Solar';
  117. }
  118. $this->_setDirs();
  119. $this->_loadTemplates();
  120. // convert
  121. $this->_outln('Convert docs to docbook files.');
  122. $this->_buildFoundation($vendor);
  123. $this->_convertPackages();
  124. $this->_convertClasses();
  125. // done!
  126. $time = time() - $begin;
  127. $this->_outln("Wiki docs converted to DocBook in $time seconds.");
  128. }
  129. /**
  130. *
  131. * Sets directory paths for reading and writing.
  132. *
  133. * @return void
  134. *
  135. */
  136. protected function _setDirs()
  137. {
  138. // get the source class dir
  139. $class_dir = $this->_options['class_dir'];
  140. if ($class_dir) {
  141. $this->_class_dir = Solar_Dir::fix($class_dir);
  142. }
  143. // do we have a class dir?
  144. if (! $this->_class_dir) {
  145. throw $this->_exception('ERR_NO_CLASS_DIR');
  146. }
  147. // get the source package dir (if any)
  148. $package_dir = $this->_options['package_dir'];
  149. if ($package_dir) {
  150. $this->_package_dir = Solar_Dir::fix($package_dir);
  151. }
  152. // do we have a package dir?
  153. if (! $this->_package_dir) {
  154. throw $this->_exception('ERR_NO_PACKAGE_DIR');
  155. }
  156. // get the target docbook dir (if any)
  157. $docbook_dir = $this->_options['docbook_dir'];
  158. if ($docbook_dir) {
  159. $this->_docbook_dir = Solar_Dir::fix($docbook_dir);
  160. }
  161. // do we have a docbook dir?
  162. if (! $this->_docbook_dir) {
  163. throw $this->_exception('ERR_NO_DOCBOOK_DIR');
  164. }
  165. }
  166. /**
  167. *
  168. * Loads DocBook template files from the Data directory.
  169. *
  170. * @return void
  171. *
  172. */
  173. protected function _loadTemplates()
  174. {
  175. $dir = Solar_Class::dir($this, 'Data');
  176. $list = glob("$dir/*.txt");
  177. foreach ($list as $file) {
  178. $name = basename($file);
  179. $name = str_replace('.txt', '.xml', $name);
  180. $this->_templates[$name] = file_get_contents($file);
  181. }
  182. }
  183. /**
  184. *
  185. * Writes the top-level apidoc DocBook files.
  186. *
  187. * @param string $vendor The top-level vendor class we're building API
  188. * docs for.
  189. *
  190. * @return void
  191. *
  192. */
  193. protected function _buildFoundation($vendor)
  194. {
  195. $this->_out("Build foundation ... ");
  196. $tmpl = 'apidoc.xml';
  197. $data = array('{:vendor}' => $vendor);
  198. $file = 'apidoc.xml';
  199. $this->_save($tmpl, $data, $file);
  200. $this->_outln("done.");
  201. }
  202. /**
  203. *
  204. * Converts all wiki-based package docs to DocBook.
  205. *
  206. * @return void
  207. *
  208. */
  209. protected function _convertPackages()
  210. {
  211. $list = glob("{$this->_package_dir}/*");
  212. foreach ($list as $key => $val) {
  213. $name = basename($val);
  214. $list[$key] = $name;
  215. }
  216. $key = array_search('index', $list);
  217. unset($list[$key]);
  218. $this->_out('Converting packages ... ');
  219. $this->_convertPackageToc($list);
  220. $this->_convertPackageIndex($list);
  221. foreach ($list as $package) {
  222. $this->_convertPackage($package);
  223. }
  224. $this->_outln('done.');
  225. }
  226. /**
  227. *
  228. * Converts the wiki-based package table of contents to DocBook.
  229. *
  230. * @param array $list The list of package names.
  231. *
  232. * @return void
  233. *
  234. */
  235. protected function _convertPackageToc($list)
  236. {
  237. $xinc = array();
  238. foreach ($list as $package) {
  239. $href = "package/$package.xml";
  240. $xinc[] = " <xi:include href=\"$href\" />";
  241. }
  242. $xinc = implode("\n", $xinc);
  243. $tmpl = 'package.xml';
  244. $data = array('{:xinc}' => $xinc);
  245. $file = 'apidoc/package.xml';
  246. $this->_save($tmpl, $data, $file);
  247. }
  248. /**
  249. *
  250. * Converts the wiki-based package index to DocBook.
  251. *
  252. * @param array $list The list of package names.
  253. *
  254. * @return void
  255. *
  256. */
  257. protected function _convertPackageIndex($list)
  258. {
  259. $packages = file_get_contents("{$this->_package_dir}/index");
  260. $tmpl = 'package-index.xml';
  261. $data = array(
  262. '{:packages}' => $packages,
  263. );
  264. $file = 'apidoc/package/index.xml';
  265. $this->_saveMarkdown($tmpl, $data, $file);
  266. }
  267. /**
  268. *
  269. * Converts a single wiki-based package file to DocBook.
  270. *
  271. * @param string $package The package name.
  272. *
  273. * @return void
  274. *
  275. */
  276. protected function _convertPackage($package)
  277. {
  278. $tmpl = 'package-overview.xml';
  279. $data = array(
  280. '{:name}' => $package,
  281. '{:info}' => file_get_contents("$this->_package_dir/$package"),
  282. );
  283. $file = "apidoc/package/$package.xml";
  284. $this->_saveMarkdown($tmpl, $data, $file);
  285. }
  286. /**
  287. *
  288. * Converts all wiki-based class files to DocBook.
  289. *
  290. * @return void
  291. *
  292. */
  293. protected function _convertClasses()
  294. {
  295. $list = glob("{$this->_class_dir}/*");
  296. foreach ($list as $key => $val) {
  297. $name = basename($val);
  298. $list[$key] = $name;
  299. }
  300. $key = array_search('index', $list);
  301. unset($list[$key]);
  302. $this->_out("Converting classes TOC and index ... ");
  303. $this->_convertClassToc($list);
  304. $this->_convertClassIndex($list);
  305. $this->_outln('done.');
  306. $this->_outln("Convert classes.");
  307. foreach ($list as $class) {
  308. $this->_convertClass($class);
  309. }
  310. }
  311. /**
  312. *
  313. * Converts all wiki-based class files to DocBook.
  314. *
  315. * @param array $list The list of class names.
  316. *
  317. * @return void
  318. *
  319. */
  320. protected function _convertClassToc($list)
  321. {
  322. $xinc = array();
  323. foreach ($list as $class) {
  324. $href = "class/$class.xml";
  325. $xinc[] = " <xi:include href=\"$href\" />";
  326. }
  327. $xinc = implode("\n", $xinc);
  328. $tmpl = 'class.xml';
  329. $data = array('{:xinc}' => $xinc);
  330. $file = 'apidoc/class.xml';
  331. $this->_save($tmpl, $data, $file);
  332. }
  333. /**
  334. *
  335. * Converts the wiki-based class index to DocBook.
  336. *
  337. * @param array $list The list of package names.
  338. *
  339. * @return void
  340. *
  341. */
  342. protected function _convertClassIndex($list)
  343. {
  344. $classes = file_get_contents("{$this->_class_dir}/index");
  345. $tmpl = 'class-index.xml';
  346. $data = array(
  347. '{:classes}' => $classes,
  348. );
  349. $file = 'apidoc/class/index.xml';
  350. $this->_saveMarkdown($tmpl, $data, $file);
  351. }
  352. /**
  353. *
  354. * Converts a single wiki-based class file set to DocBook.
  355. *
  356. * @param string $class The class file set to convert.
  357. *
  358. * @return void
  359. *
  360. */
  361. protected function _convertClass($class)
  362. {
  363. $this->_out("$class ... ");
  364. // file set for the class
  365. $list = glob("{$this->_class_dir}/$class/*");
  366. // toc: part 1
  367. $xinc = array();
  368. $skip = array('Overview', 'Config', 'Constants', 'Properties', 'Methods');
  369. foreach ($skip as $name) {
  370. if ($name == 'index') {
  371. continue;
  372. }
  373. $xinc[] = " <xi:include href=\"$class/$name.xml\" />";
  374. }
  375. // toc: part 2
  376. $skip[] = 'index';
  377. foreach ($list as $name) {
  378. $name = preg_replace('[^A-Za-z0-9_]', '', basename($name));
  379. if (in_array($name, $skip)) {
  380. continue;
  381. }
  382. $xinc[] = " <xi:include href=\"$class/$name.xml\" />";
  383. }
  384. // write toc
  385. $xinc = implode("\n", $xinc);
  386. $tmpl = 'class-toc.xml';
  387. $data = array(
  388. '{:class}' => $class,
  389. '{:xinc}' => $xinc,
  390. );
  391. $file = "apidoc/class/$class.xml";
  392. $this->_save($tmpl, $data, $file);
  393. // overview
  394. $tmpl = 'class-overview.xml';
  395. $data = array(
  396. '{:class}' => $class,
  397. '{:info}' => file_get_contents("$this->_class_dir/$class/Overview"),
  398. );
  399. $file = "apidoc/class/$class/Overview.xml";
  400. $this->_saveMarkdown($tmpl, $data, $file);
  401. // config
  402. $tmpl = 'class-config.xml';
  403. $data = array(
  404. '{:class}' => $class,
  405. '{:info}' => file_get_contents("$this->_class_dir/$class/Config"),
  406. );
  407. $file = "apidoc/class/$class/Config.xml";
  408. $this->_saveMarkdown($tmpl, $data, $file);
  409. // constants
  410. $tmpl = 'class-constants.xml';
  411. $data = array(
  412. '{:class}' => $class,
  413. '{:info}' => file_get_contents("$this->_class_dir/$class/Constants"),
  414. );
  415. $file = "apidoc/class/$class/Constants.xml";
  416. $this->_saveMarkdown($tmpl, $data, $file);
  417. // properties
  418. $tmpl = 'class-properties.xml';
  419. $data = array(
  420. '{:class}' => $class,
  421. '{:info}' => file_get_contents("$this->_class_dir/$class/Properties"),
  422. );
  423. $file = "apidoc/class/$class/Properties.xml";
  424. $this->_saveMarkdown($tmpl, $data, $file);
  425. // all methods
  426. $tmpl = 'class-methods.xml';
  427. $data = array(
  428. '{:class}' => $class,
  429. '{:info}' => file_get_contents("$this->_class_dir/$class/Methods"),
  430. );
  431. $file = "apidoc/class/$class/Methods.xml";
  432. $this->_saveMarkdown($tmpl, $data, $file);
  433. // individual methods
  434. $skip = array('index', 'Overview', 'Config', 'Constants', 'Properties', 'Methods');
  435. foreach ($list as $method) {
  436. $method = basename($method);
  437. if (in_array($method, $skip)) {
  438. continue;
  439. }
  440. $tmpl = 'class-method.xml';
  441. $name = preg_replace('/[^A-Za-z0-9_]/', '', $method);
  442. $data = array(
  443. '{:class}' => $class,
  444. '{:method}' => $method,
  445. '{:xmlid}' => $name,
  446. '{:info}' => file_get_contents("$this->_class_dir/$class/$method"),
  447. );
  448. $file = "apidoc/class/$class/$method.xml";
  449. $this->_saveMarkdown($tmpl, $data, $file);
  450. }
  451. $this->_outln('done.');
  452. }
  453. /**
  454. *
  455. * Writes a file to the target directory.
  456. *
  457. * @param string $tmpl The XML template to use.
  458. *
  459. * @param array $data Data to populate into the template.
  460. *
  461. * @param string $file The DocBook file name.
  462. *
  463. * @return void
  464. *
  465. */
  466. protected function _save($tmpl, $data, $file)
  467. {
  468. // save to file
  469. $file = "{$this->_docbook_dir}/$file";
  470. $dir = dirname($file);
  471. if (! is_dir($dir)) {
  472. $result = mkdir($dir, 0777, true);
  473. if (! $result) {
  474. throw $this->_exception('ERR_MKDIR_FAILED', array(
  475. 'dir' => $dir,
  476. 'file' => $file,
  477. ));
  478. }
  479. }
  480. // interpolate into the template
  481. $text = $this->_templates[$tmpl];
  482. $text = str_replace(
  483. array_keys($data),
  484. array_values($data),
  485. $text
  486. );
  487. // save to the target file
  488. file_put_contents($file, $text);
  489. }
  490. /**
  491. *
  492. * Transforms from wiki markup to DocBook, and saves it to the target
  493. * directory.
  494. *
  495. * @param string $tmpl The XML template to use.
  496. *
  497. * @param array $data Data to populate into the template.
  498. *
  499. * @param string $file The DocBook file name.
  500. *
  501. * @return void
  502. *
  503. */
  504. protected function _saveMarkdown($tmpl, $data, $file)
  505. {
  506. foreach ($data as $key => $val) {
  507. // only transform if there is at least one newline in it
  508. if (strpos($val, "\n")) {
  509. $data[$key] = $this->_markdown->transform($val);
  510. }
  511. }
  512. $this->_save($tmpl, $data, $file);
  513. }
  514. }