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