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$
|
||||
* @link http://pear.php.net/package/Text_Figlet
|
||||
*/
|
||||
require_once 'PEAR.php';
|
||||
|
||||
/**
|
||||
* ASCII art text creation
|
||||
|
@ -113,22 +112,9 @@ class Text_Figlet
|
|||
{
|
||||
$this->font = array();
|
||||
if (!file_exists($filename)) {
|
||||
//if it does not exist, try the Text_Figlet data directory
|
||||
include_once 'PEAR/Config.php';
|
||||
|
||||
$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);
|
||||
}
|
||||
return self::raiseError('Figlet font file "'
|
||||
. $filename
|
||||
. '" cannot be found', 1);
|
||||
}
|
||||
|
||||
$this->font_comment = '';
|
||||
|
@ -139,7 +125,7 @@ class Text_Figlet
|
|||
$compressed = true;
|
||||
|
||||
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.',
|
||||
3);
|
||||
}
|
||||
|
@ -148,14 +134,14 @@ class Text_Figlet
|
|||
}
|
||||
|
||||
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) {
|
||||
/* ZIPed font */
|
||||
if (fread($fp, 2) == 'PK') {
|
||||
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.',
|
||||
5);
|
||||
}
|
||||
|
@ -163,14 +149,14 @@ class Text_Figlet
|
|||
fclose($fp);
|
||||
|
||||
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));
|
||||
zip_close($fp);
|
||||
|
||||
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;
|
||||
|
@ -193,7 +179,7 @@ class Text_Figlet
|
|||
$header = explode(' ', fgets($fp, 2048));
|
||||
|
||||
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,,,
|
||||
|
@ -381,9 +367,9 @@ class Text_Figlet
|
|||
$str = strtr(implode("\n", $out), $trans);
|
||||
|
||||
if ($inhtml) {
|
||||
return '<nobr>'.
|
||||
nl2br(str_replace(' ', ' ', htmlspecialchars($str))).
|
||||
'</nobr>';
|
||||
self::raiseError(
|
||||
'Do not use the HTML escaping provided by this class in '.
|
||||
'a Phabricator context.');
|
||||
}
|
||||
|
||||
return $str;
|
||||
|
@ -506,5 +492,9 @@ class Text_Figlet
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private static function raiseError($message, $code = 1) {
|
||||
throw new Exception($message);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
|
@ -7,33 +7,28 @@ final class PhabricatorRemarkupFigletBlockInterpreter
|
|||
return 'figlet';
|
||||
}
|
||||
|
||||
/**
|
||||
* @phutil-external-symbol class Text_Figlet
|
||||
*/
|
||||
public function markupContent($content, array $argv) {
|
||||
if (!Filesystem::binaryExists('figlet')) {
|
||||
return $this->markupError(
|
||||
pht(
|
||||
'Unable to locate the `%s` binary. Install figlet.',
|
||||
'figlet'));
|
||||
$map = self::getFigletMap();
|
||||
|
||||
$font = idx($argv, 'font');
|
||||
$font = phutil_utf8_strtolower($font);
|
||||
if (empty($map[$font])) {
|
||||
$font = 'standard';
|
||||
}
|
||||
|
||||
$font = idx($argv, 'font', 'standard');
|
||||
$safe_font = preg_replace('/[^0-9a-zA-Z-_.]/', '', $font);
|
||||
$future = id(new ExecFuture('figlet -f %s', $safe_font))
|
||||
->setTimeout(15)
|
||||
->write(trim($content, "\n"));
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require_once $root.'/externals/pear-figlet/Text/Figlet.php';
|
||||
|
||||
list($err, $stdout, $stderr) = $future->resolve();
|
||||
|
||||
if ($err) {
|
||||
return $this->markupError(
|
||||
pht(
|
||||
'Execution of `%s` failed: %s',
|
||||
'figlet',
|
||||
$stderr));
|
||||
}
|
||||
$figlet = new Text_Figlet();
|
||||
$figlet->loadFont($map[$font]);
|
||||
|
||||
$result = $figlet->lineEcho($content);
|
||||
|
||||
if ($this->getEngine()->isTextMode()) {
|
||||
return $stdout;
|
||||
return $result;
|
||||
}
|
||||
|
||||
return phutil_tag(
|
||||
|
@ -41,7 +36,30 @@ final class PhabricatorRemarkupFigletBlockInterpreter
|
|||
array(
|
||||
'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