mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 11:30:55 +01:00
Use PEAR Text_Figlet to render figlet fonts
Summary: Ref T7785. Makes Figlet available without installing the `figlet` package. The PEAR Text_Figlet code is really sketchy and includes this API, which is quite marvelous: ``` function loadFont($filename, $loadgerman = true) ``` At some point, this should probably be rewritten into a modern style, but it's not trivial since the figlet file format and rendering engine are somewhat complicated. I made some adjustments: - Broke the dependency on the PEAR core. - Prevented it from doing any wrong HTML escaping. - Looked through it for any glaring security or correctness problems. This code isn't very pretty or modern, but as far as I can tell it's safe and does render Figlet fonts in a reasonable way. Test Plan: {F803268} Reviewers: chad Reviewed By: chad Maniphest Tasks: T9408, T7785 Differential Revision: https://secure.phabricator.com/D14102
This commit is contained in:
parent
935ced1edd
commit
6bd8ee861c
2 changed files with 56 additions and 48 deletions
44
externals/pear-figlet/Text/Figlet.php
vendored
44
externals/pear-figlet/Text/Figlet.php
vendored
|
@ -15,7 +15,6 @@
|
||||||
* @version CVS: $Id$
|
* @version CVS: $Id$
|
||||||
* @link http://pear.php.net/package/Text_Figlet
|
* @link http://pear.php.net/package/Text_Figlet
|
||||||
*/
|
*/
|
||||||
require_once 'PEAR.php';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ASCII art text creation
|
* ASCII art text creation
|
||||||
|
@ -113,22 +112,9 @@ class Text_Figlet
|
||||||
{
|
{
|
||||||
$this->font = array();
|
$this->font = array();
|
||||||
if (!file_exists($filename)) {
|
if (!file_exists($filename)) {
|
||||||
//if it does not exist, try the Text_Figlet data directory
|
return self::raiseError('Figlet font file "'
|
||||||
include_once 'PEAR/Config.php';
|
. $filename
|
||||||
|
. '" cannot be found', 1);
|
||||||
$config = PEAR_Config::singleton();
|
|
||||||
$fontdir = $config->get('data_dir') . '/Text_Figlet/fonts/';
|
|
||||||
|
|
||||||
//only for filenames without path separators
|
|
||||||
if (strpos($filename, '/') === false
|
|
||||||
&& file_exists($fontdir . $filename)
|
|
||||||
) {
|
|
||||||
$filename = $fontdir . $filename;
|
|
||||||
} else {
|
|
||||||
return PEAR::raiseError('Figlet font file "'
|
|
||||||
. $filename
|
|
||||||
. '" cannot be found', 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->font_comment = '';
|
$this->font_comment = '';
|
||||||
|
@ -139,7 +125,7 @@ class Text_Figlet
|
||||||
$compressed = true;
|
$compressed = true;
|
||||||
|
|
||||||
if (!function_exists('gzcompress')) {
|
if (!function_exists('gzcompress')) {
|
||||||
return PEAR::raiseError('Cannot load gzip compressed fonts since'
|
return self::raiseError('Cannot load gzip compressed fonts since'
|
||||||
. ' gzcompress() is not available.',
|
. ' gzcompress() is not available.',
|
||||||
3);
|
3);
|
||||||
}
|
}
|
||||||
|
@ -148,14 +134,14 @@ class Text_Figlet
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($fp = fopen($filename, 'rb'))) {
|
if (!($fp = fopen($filename, 'rb'))) {
|
||||||
return PEAR::raiseError('Cannot open figlet font file ' . $filename, 2);
|
return self::raiseError('Cannot open figlet font file ' . $filename, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$compressed) {
|
if (!$compressed) {
|
||||||
/* ZIPed font */
|
/* ZIPed font */
|
||||||
if (fread($fp, 2) == 'PK') {
|
if (fread($fp, 2) == 'PK') {
|
||||||
if (!function_exists('zip_open')) {
|
if (!function_exists('zip_open')) {
|
||||||
return PEAR::raiseError('Cannot load ZIP compressed fonts since'
|
return self::raiseError('Cannot load ZIP compressed fonts since'
|
||||||
. ' ZIP PHP extension is not available.',
|
. ' ZIP PHP extension is not available.',
|
||||||
5);
|
5);
|
||||||
}
|
}
|
||||||
|
@ -163,14 +149,14 @@ class Text_Figlet
|
||||||
fclose($fp);
|
fclose($fp);
|
||||||
|
|
||||||
if (!($fp = zip_open($filename))) {
|
if (!($fp = zip_open($filename))) {
|
||||||
return PEAR::raiseError('Cannot open figlet font file ' . $filename, 2);
|
return self::raiseError('Cannot open figlet font file ' . $filename, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = zip_entry_name(zip_read($fp));
|
$name = zip_entry_name(zip_read($fp));
|
||||||
zip_close($fp);
|
zip_close($fp);
|
||||||
|
|
||||||
if (!($fp = fopen('zip://' . realpath($filename) . '#' . $name, 'rb'))) {
|
if (!($fp = fopen('zip://' . realpath($filename) . '#' . $name, 'rb'))) {
|
||||||
return PEAR::raiseError('Cannot open figlet font file ' . $filename, 2);
|
return self::raiseError('Cannot open figlet font file ' . $filename, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$compressed = true;
|
$compressed = true;
|
||||||
|
@ -193,7 +179,7 @@ class Text_Figlet
|
||||||
$header = explode(' ', fgets($fp, 2048));
|
$header = explode(' ', fgets($fp, 2048));
|
||||||
|
|
||||||
if (substr($header[0], 0, 5) <> 'flf2a') {
|
if (substr($header[0], 0, 5) <> 'flf2a') {
|
||||||
return PEAR::raiseError('Unknown FIGlet font format.', 4);
|
return self::raiseError('Unknown FIGlet font format.', 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@list ($this->hardblank, $this->height,,,
|
@list ($this->hardblank, $this->height,,,
|
||||||
|
@ -381,9 +367,9 @@ class Text_Figlet
|
||||||
$str = strtr(implode("\n", $out), $trans);
|
$str = strtr(implode("\n", $out), $trans);
|
||||||
|
|
||||||
if ($inhtml) {
|
if ($inhtml) {
|
||||||
return '<nobr>'.
|
self::raiseError(
|
||||||
nl2br(str_replace(' ', ' ', htmlspecialchars($str))).
|
'Do not use the HTML escaping provided by this class in '.
|
||||||
'</nobr>';
|
'a Phabricator context.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $str;
|
return $str;
|
||||||
|
@ -506,5 +492,9 @@ class Text_Figlet
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static function raiseError($message, $code = 1) {
|
||||||
|
throw new Exception($message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
?>
|
|
||||||
|
|
|
@ -7,33 +7,28 @@ final class PhabricatorRemarkupFigletBlockInterpreter
|
||||||
return 'figlet';
|
return 'figlet';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phutil-external-symbol class Text_Figlet
|
||||||
|
*/
|
||||||
public function markupContent($content, array $argv) {
|
public function markupContent($content, array $argv) {
|
||||||
if (!Filesystem::binaryExists('figlet')) {
|
$map = self::getFigletMap();
|
||||||
return $this->markupError(
|
|
||||||
pht(
|
$font = idx($argv, 'font');
|
||||||
'Unable to locate the `%s` binary. Install figlet.',
|
$font = phutil_utf8_strtolower($font);
|
||||||
'figlet'));
|
if (empty($map[$font])) {
|
||||||
|
$font = 'standard';
|
||||||
}
|
}
|
||||||
|
|
||||||
$font = idx($argv, 'font', 'standard');
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
$safe_font = preg_replace('/[^0-9a-zA-Z-_.]/', '', $font);
|
require_once $root.'/externals/pear-figlet/Text/Figlet.php';
|
||||||
$future = id(new ExecFuture('figlet -f %s', $safe_font))
|
|
||||||
->setTimeout(15)
|
|
||||||
->write(trim($content, "\n"));
|
|
||||||
|
|
||||||
list($err, $stdout, $stderr) = $future->resolve();
|
$figlet = new Text_Figlet();
|
||||||
|
$figlet->loadFont($map[$font]);
|
||||||
if ($err) {
|
|
||||||
return $this->markupError(
|
|
||||||
pht(
|
|
||||||
'Execution of `%s` failed: %s',
|
|
||||||
'figlet',
|
|
||||||
$stderr));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$result = $figlet->lineEcho($content);
|
||||||
|
|
||||||
if ($this->getEngine()->isTextMode()) {
|
if ($this->getEngine()->isTextMode()) {
|
||||||
return $stdout;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return phutil_tag(
|
return phutil_tag(
|
||||||
|
@ -41,7 +36,30 @@ final class PhabricatorRemarkupFigletBlockInterpreter
|
||||||
array(
|
array(
|
||||||
'class' => 'PhabricatorMonospaced remarkup-figlet',
|
'class' => 'PhabricatorMonospaced remarkup-figlet',
|
||||||
),
|
),
|
||||||
$stdout);
|
$result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function getFigletMap() {
|
||||||
|
$root = dirname(phutil_get_library_root('phabricator'));
|
||||||
|
|
||||||
|
$dirs = array(
|
||||||
|
$root.'/externals/figlet/fonts/',
|
||||||
|
$root.'/externals/pear-figlet/fonts/',
|
||||||
|
$root.'/resources/figlet/custom/',
|
||||||
|
);
|
||||||
|
|
||||||
|
$map = array();
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
foreach (Filesystem::listDirectory($dir, false) as $file) {
|
||||||
|
if (preg_match('/\.flf\z/', $file)) {
|
||||||
|
$name = phutil_utf8_strtolower($file);
|
||||||
|
$name = preg_replace('/\.flf\z/', '', $name);
|
||||||
|
$map[$name] = $dir.$file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $map;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue