1<?php 2 3/** 4 * Format text for terminal output. This function behaves like `sprintf`, 5 * except that all the normal conversions (like "%s") will be properly escaped, 6 * and additional conversions are supported: 7 * 8 * %B (Block) 9 * Escapes text, but preserves tabs and newlines. 10 * 11 * %R (Raw String) 12 * Inserts raw, unescaped text. DANGEROUS! 13 * 14 * Particularly, this will escape terminal control characters. 15 */ 16function tsprintf($pattern /* , ... */) { 17 $args = func_get_args(); 18 $args[0] = PhutilConsoleFormatter::interpretFormat($args[0]); 19 $string = xsprintf('xsprintf_terminal', null, $args); 20 return new PhutilTerminalString($string); 21} 22 23/** 24 * Callback for terminal encoding, see @{function:tsprintf} for use. 25 */ 26function xsprintf_terminal($userdata, &$pattern, &$pos, &$value, &$length) { 27 $type = $pattern[$pos]; 28 29 switch ($type) { 30 case 's': 31 $value = PhutilTerminalString::escapeStringValue($value, false); 32 $type = 's'; 33 break; 34 case 'B': 35 $value = PhutilTerminalString::escapeStringValue($value, true); 36 $type = 's'; 37 break; 38 case 'R': 39 $type = 's'; 40 break; 41 case 'W': 42 $value = PhutilTerminalString::escapeStringValue($value, true); 43 $value = phutil_console_wrap($value); 44 $type = 's'; 45 break; 46 case '!': 47 $value = tsprintf('<bg:yellow>** <!> %s **</bg>', $value); 48 $value = PhutilTerminalString::escapeStringValue($value, false); 49 $type = 's'; 50 break; 51 case '?': 52 $value = tsprintf('<bg:green>** ? **</bg> %s', $value); 53 $value = PhutilTerminalString::escapeStringValue($value, false); 54 $value = phutil_console_wrap($value, 6, false); 55 $type = 's'; 56 break; 57 case '>': 58 $value = tsprintf(" **$ %s**\n", $value); 59 $value = PhutilTerminalString::escapeStringValue($value, false); 60 $type = 's'; 61 break; 62 case 'd': 63 $type = 'd'; 64 break; 65 default: 66 throw new Exception( 67 pht( 68 'Unsupported escape sequence "%s" found in pattern: %s', 69 $type, 70 $pattern)); 71 break; 72 } 73 74 $pattern[$pos] = $type; 75} 76