private static function tabular(array $data, array $widths, array $align = null, $glue = ' ', $pad = ' ', $marker = '…')
 {
     $out = [];
     if (empty($align)) {
         $align = [];
     }
     foreach ($widths as $i => $w) {
         switch (get($align, $i, 'L')) {
             case 'L':
                 $align[$i] = STR_PAD_RIGHT;
                 break;
             case 'R':
                 $align[$i] = STR_PAD_LEFT;
                 break;
             case 'C':
                 $align[$i] = STR_PAD_BOTH;
                 break;
             default:
                 throw new InvalidArgumentException("Invalid value for align: {$align[$i]}");
         }
     }
     foreach ($widths as $i => $w) {
         $s = strval(get($data, $i));
         $l = taggedStrLen($s);
         if ($l > $w) {
             $out[] = taggedStrCrop($s, $w, $marker);
             //        echo taggedStrLen (taggedStrCrop ($s, $w - mb_strlen ($overflow, 'UTF-8')) . $overflow);
         } else {
             $out[] = taggedStrPad($s, $w, $align[$i], $pad);
         }
     }
     return implode($glue, $out);
 }
Exemple #2
0
/**
 * Performs cropping on strings having embedded tags.
 *
 * This is specially useful when used with color-tagged strings meant for terminal output.
 * > Ex: `"<color-name>text</color-name>"`
 *
 * @param string $str
 * @param int    $width  The desired minimum width, in characters.
 * @param string $marker The overflow marker.
 * @return string
 */
function taggedStrCrop($str, $width, $marker = '')
{
    $w = taggedStrLen($str);
    if ($w <= $width) {
        return $str;
    }
    $o = '';
    $tags = [];
    $curLen = 0;
    $markLen = mb_strlen($marker, 'UTF-8');
    while (strlen($str)) {
        if (!preg_match('/<(.*?)>/u', $str, $m, PREG_OFFSET_CAPTURE)) {
            return $o . mb_substr($str, 0, $width - $curLen - $markLen) . $marker;
        }
        list($tag, $ofs) = $m[0];
        $tagName = $m[1][0];
        $seg = mb_substr($str, 0, $ofs);
        $str = mb_substr($str, $ofs + mb_strlen($tag, 'UTF-8'));
        $segLen = mb_strlen($seg, 'UTF-8');
        $curLen += $segLen;
        if ($curLen >= $width) {
            $o .= mb_substr($seg, 0, $width - $curLen - $markLen) . $marker;
            break;
        } else {
            $o .= $seg;
        }
        if ($tag[1] == '/') {
            array_pop($tags);
        } else {
            $tags[] = $tagName;
        }
        $o .= "{$tag}";
    }
    while ($tags) {
        $o .= '</' . array_pop($tags) . '>';
    }
    return $o;
}