99namespace Inhere \Console \Util ;
1010
1111use Toolkit \Cli \ColorTag ;
12+ use Toolkit \Stdlib \Arr \ArrayHelper ;
1213use Toolkit \Stdlib \Helper \Format ;
1314use Toolkit \Stdlib \Helper \JsonHelper ;
1415use Toolkit \Stdlib \Str ;
1516use Toolkit \Sys \Sys ;
1617use function array_keys ;
1718use function array_merge ;
19+ use function array_shift ;
1820use function explode ;
1921use function implode ;
2022use function is_array ;
@@ -200,18 +202,20 @@ public static function howLongAgo(int $secs): string
200202 /**
201203 * Splice array
202204 *
203- * @param array $data
204- * e.g [
205+ * ```php
206+ * $data = [
205207 * 'system' => 'Linux',
206- * 'version' => '4.4.5',
207- * ]
208+ * 'version' => '4.4.5',
209+ * ];
210+ * ```
211+ *
212+ * @param array $data
208213 * @param array $opts
209214 *
210215 * @return string
211216 */
212217 public static function spliceKeyValue (array $ data , array $ opts = []): string
213218 {
214- $ text = '' ;
215219 $ opts = array_merge ([
216220 'leftChar ' => '' , // e.g ' ', ' * '
217221 'sepChar ' => ' ' , // e.g ' | ' OUT: key | value
@@ -221,33 +225,37 @@ public static function spliceKeyValue(array $data, array $opts = []): string
221225 'keyMinWidth ' => 8 ,
222226 'keyMaxWidth ' => 0 , // if not set, will automatic calculation
223227 'ucFirst ' => true , // upper first char for value
228+ 'endNewline ' => true , // with newline on end.
224229 ], $ opts );
225230
226231 if ($ opts ['keyMaxWidth ' ] < 1 ) {
227- $ opts ['keyMaxWidth ' ] = Helper ::getKeyMaxWidth ($ data );
232+ $ opts ['keyMaxWidth ' ] = ArrayHelper ::getKeyMaxWidth ($ data );
228233 }
229234
230235 // compare
231- if (( int ) $ opts ['keyMinWidth ' ] > $ opts ['keyMaxWidth ' ]) {
232- $ opts ['keyMaxWidth ' ] = $ opts ['keyMinWidth ' ];
236+ if ($ opts ['keyMinWidth ' ] > $ opts ['keyMaxWidth ' ]) {
237+ $ opts ['keyMaxWidth ' ] = ( int ) $ opts ['keyMinWidth ' ];
233238 }
234239
240+ $ keyWidth = $ opts ['keyMaxWidth ' ];
235241 $ keyStyle = trim ($ opts ['keyStyle ' ]);
236242 $ keyPadPos = (int )$ opts ['keyPadPos ' ];
237243
244+ $ fmtLines = [];
238245 foreach ($ data as $ key => $ value ) {
239- $ hasKey = !is_int ($ key );
240- $ text . = $ opts ['leftChar ' ];
246+ $ hasKey = !is_int ($ key );
247+ $ fmtLine = $ opts ['leftChar ' ];
241248
242- if ($ hasKey && $ opts [ ' keyMaxWidth ' ] ) {
243- $ key = Str::pad ((string )$ key , $ opts [ ' keyMaxWidth ' ] , ' ' , $ keyPadPos );
244- $ text .= ColorTag::wrap ($ key , $ keyStyle ) . $ opts ['sepChar ' ];
249+ if ($ hasKey && $ keyWidth ) {
250+ $ strKey = Str::pad ((string )$ key , $ keyWidth , ' ' , $ keyPadPos );
251+ $ fmtLine .= ColorTag::wrap ($ strKey , $ keyStyle ) . $ opts ['sepChar ' ];
245252 }
246253
254+ $ lines = [];
255+
247256 // if value is array, translate array to string
248257 if (is_array ($ value )) {
249258 $ temp = '[ ' ;
250-
251259 foreach ($ value as $ k => $ val ) {
252260 if (is_bool ($ val )) {
253261 $ val = $ val ? '(True) ' : '(False) ' ;
@@ -261,14 +269,37 @@ public static function spliceKeyValue(array $data, array $opts = []): string
261269 $ value = rtrim ($ temp , ' , ' ) . '] ' ;
262270 } elseif (is_bool ($ value )) {
263271 $ value = $ value ? '(True) ' : '(False) ' ;
264- } else {
272+ } else { // to string.
265273 $ value = (string )$ value ;
274+
275+ // multi line
276+ if ($ hasKey && strpos ($ value , "\n" ) > 0 ) {
277+ $ lines = explode ("\n" , $ value );
278+ $ value = array_shift ($ lines );
279+ }
266280 }
267281
282+ // uc-first
268283 $ value = $ hasKey && $ opts ['ucFirst ' ] ? ucfirst ($ value ) : $ value ;
269- $ text .= ColorTag::wrap ($ value , $ opts ['valStyle ' ]) . "\n" ;
284+
285+ // append value.
286+ $ fmtLine .= ColorTag::wrap ($ value , $ opts ['valStyle ' ]);
287+ // append fmt line.
288+ $ fmtLines [] = $ fmtLine ;
289+
290+ // value has multi line
291+ if ($ lines ) {
292+ $ linePrefix = $ opts ['leftChar ' ] . Str::repeat (' ' , $ keyWidth + 1 ) . $ opts ['sepChar ' ];
293+ foreach ($ lines as $ line ) {
294+ $ fmtLines [] = $ linePrefix . $ line ;
295+ }
296+ }
297+ }
298+
299+ if ($ opts ['endNewline ' ]) {
300+ return implode ("\n" , $ fmtLines ) . "\n" ;
270301 }
271302
272- return $ text ;
303+ return implode ( "\n" , $ fmtLines ) ;
273304 }
274305}
0 commit comments