%s', htmlspecialchars( $value ) ); } public static function h1( string $value ): string { return sprintf( '%s', htmlspecialchars( $value ) ); } public static function h2( string $value ): string { return sprintf( '%s', htmlspecialchars( $value ) ); } public static function h3( string $value ): string { return sprintf( '%s', htmlspecialchars( $value ) ); } public static function link( string $href, string $title, string $value ): string { return sprintf( '%s', htmlspecialchars( $href ), htmlspecialchars( $title ), htmlspecialchars( $value ) ); } public static function list( string $value ): string { return sprintf( '* %s', // @TODO htmlspecialchars( $value ) ); } public static function quote( string $value ): string { return sprintf( '%s', htmlspecialchars( $value ) ); } public static function text( string $value, int $width = self::WRAP_WIDTH ): string { return self::_wrap( htmlspecialchars( $value ), $width ); } public static function pre( string $value ): string { return htmlspecialchars( $value ); } public static function tag( string $const, bool $close ): string { if (in_array($const, [self::TAG_CODE])) { return sprintf( $close ? '' : '<%s>', $const ); } throw new Exception; } protected static function _width( string $markup ): ?int { $label = new GtkLabel; $label->set_use_markup( true ); $label->set_markup( $markup, -1 ); if ($size = $label->get_layout()->get_pixel_size()) { $label->destroy(); return $size['width']; } return null; } protected static function _wrap( string $string, int $width, int $line = 1, array $words = [], array $lines = [] ): string { foreach (explode(' ', $string) as $word) { if (isset($words[$line])) { $try = implode( ' ' , $words[$line] ) . ' ' . $word; if (self::_width($try) > $width) { $line++; } } $words[$line][] = $word; } foreach ($words as $values) { $lines[] = implode( ' ', $values ); } return implode( PHP_EOL, $lines ); } }