Mercurial > hg > isophonics-drupal-site
comparison vendor/psy/psysh/src/Psy/Formatter/DocblockFormatter.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of Psy Shell. | |
5 * | |
6 * (c) 2012-2017 Justin Hileman | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Psy\Formatter; | |
13 | |
14 use Psy\Util\Docblock; | |
15 use Symfony\Component\Console\Formatter\OutputFormatter; | |
16 | |
17 /** | |
18 * A pretty-printer for docblocks. | |
19 */ | |
20 class DocblockFormatter implements Formatter | |
21 { | |
22 private static $vectorParamTemplates = array( | |
23 'type' => 'info', | |
24 'var' => 'strong', | |
25 ); | |
26 | |
27 /** | |
28 * Format a docblock. | |
29 * | |
30 * @param \Reflector $reflector | |
31 * | |
32 * @return string Formatted docblock | |
33 */ | |
34 public static function format(\Reflector $reflector) | |
35 { | |
36 $docblock = new Docblock($reflector); | |
37 $chunks = array(); | |
38 | |
39 if (!empty($docblock->desc)) { | |
40 $chunks[] = '<comment>Description:</comment>'; | |
41 $chunks[] = self::indent(OutputFormatter::escape($docblock->desc), ' '); | |
42 $chunks[] = ''; | |
43 } | |
44 | |
45 if (!empty($docblock->tags)) { | |
46 foreach ($docblock::$vectors as $name => $vector) { | |
47 if (isset($docblock->tags[$name])) { | |
48 $chunks[] = sprintf('<comment>%s:</comment>', self::inflect($name)); | |
49 $chunks[] = self::formatVector($vector, $docblock->tags[$name]); | |
50 $chunks[] = ''; | |
51 } | |
52 } | |
53 | |
54 $tags = self::formatTags(array_keys($docblock::$vectors), $docblock->tags); | |
55 if (!empty($tags)) { | |
56 $chunks[] = $tags; | |
57 $chunks[] = ''; | |
58 } | |
59 } | |
60 | |
61 return rtrim(implode("\n", $chunks)); | |
62 } | |
63 | |
64 /** | |
65 * Format a docblock vector, for example, `@throws`, `@param`, or `@return`. | |
66 * | |
67 * @see DocBlock::$vectors | |
68 * | |
69 * @param array $vector | |
70 * @param array $lines | |
71 * | |
72 * @return string | |
73 */ | |
74 private static function formatVector(array $vector, array $lines) | |
75 { | |
76 $template = array(' '); | |
77 foreach ($vector as $type) { | |
78 $max = 0; | |
79 foreach ($lines as $line) { | |
80 $chunk = $line[$type]; | |
81 $cur = empty($chunk) ? 0 : strlen($chunk) + 1; | |
82 if ($cur > $max) { | |
83 $max = $cur; | |
84 } | |
85 } | |
86 | |
87 $template[] = self::getVectorParamTemplate($type, $max); | |
88 } | |
89 $template = implode(' ', $template); | |
90 | |
91 return implode("\n", array_map(function ($line) use ($template) { | |
92 $escaped = array_map(array('Symfony\Component\Console\Formatter\OutputFormatter', 'escape'), $line); | |
93 | |
94 return rtrim(vsprintf($template, $escaped)); | |
95 }, $lines)); | |
96 } | |
97 | |
98 /** | |
99 * Format docblock tags. | |
100 * | |
101 * @param array $skip Tags to exclude | |
102 * @param array $tags Tags to format | |
103 * | |
104 * @return string formatted tags | |
105 */ | |
106 private static function formatTags(array $skip, array $tags) | |
107 { | |
108 $chunks = array(); | |
109 | |
110 foreach ($tags as $name => $values) { | |
111 if (in_array($name, $skip)) { | |
112 continue; | |
113 } | |
114 | |
115 foreach ($values as $value) { | |
116 $chunks[] = sprintf('<comment>%s%s</comment> %s', self::inflect($name), empty($value) ? '' : ':', OutputFormatter::escape($value)); | |
117 } | |
118 | |
119 $chunks[] = ''; | |
120 } | |
121 | |
122 return implode("\n", $chunks); | |
123 } | |
124 | |
125 /** | |
126 * Get a docblock vector template. | |
127 * | |
128 * @param string $type Vector type | |
129 * @param int $max Pad width | |
130 * | |
131 * @return string | |
132 */ | |
133 private static function getVectorParamTemplate($type, $max) | |
134 { | |
135 if (!isset(self::$vectorParamTemplates[$type])) { | |
136 return sprintf('%%-%ds', $max); | |
137 } | |
138 | |
139 return sprintf('<%s>%%-%ds</%s>', self::$vectorParamTemplates[$type], $max, self::$vectorParamTemplates[$type]); | |
140 } | |
141 | |
142 /** | |
143 * Indent a string. | |
144 * | |
145 * @param string $text String to indent | |
146 * @param string $indent (default: ' ') | |
147 * | |
148 * @return string | |
149 */ | |
150 private static function indent($text, $indent = ' ') | |
151 { | |
152 return $indent . str_replace("\n", "\n" . $indent, $text); | |
153 } | |
154 | |
155 /** | |
156 * Convert underscored or whitespace separated words into sentence case. | |
157 * | |
158 * @param string $text | |
159 * | |
160 * @return string | |
161 */ | |
162 private static function inflect($text) | |
163 { | |
164 $words = trim(preg_replace('/[\s_-]+/', ' ', preg_replace('/([a-z])([A-Z])/', '$1 $2', $text))); | |
165 | |
166 return implode(' ', array_map('ucfirst', explode(' ', $words))); | |
167 } | |
168 } |