Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15385915
D7332.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
13 KB
Referenced Files
None
Subscribers
None
D7332.id.diff
View Options
Index: src/__celerity_resource_map__.php
===================================================================
--- src/__celerity_resource_map__.php
+++ src/__celerity_resource_map__.php
@@ -3433,7 +3433,7 @@
),
'phabricator-remarkup-css' =>
array(
- 'uri' => '/res/7e8988dd/rsrc/css/core/remarkup.css',
+ 'uri' => '/res/4c313572/rsrc/css/core/remarkup.css',
'type' => 'css',
'requires' =>
array(
@@ -4273,7 +4273,7 @@
), array(
'packages' =>
array(
- 'a4e76ef8' =>
+ '30de5267' =>
array(
'name' => 'core.pkg.css',
'symbols' =>
@@ -4322,7 +4322,7 @@
41 => 'phabricator-tag-view-css',
42 => 'phui-list-view-css',
),
- 'uri' => '/res/pkg/a4e76ef8/core.pkg.css',
+ 'uri' => '/res/pkg/30de5267/core.pkg.css',
'type' => 'css',
),
'6041c6c8' =>
@@ -4514,15 +4514,15 @@
),
'reverse' =>
array(
- 'aphront-dialog-view-css' => 'a4e76ef8',
- 'aphront-error-view-css' => 'a4e76ef8',
- 'aphront-list-filter-view-css' => 'a4e76ef8',
- 'aphront-pager-view-css' => 'a4e76ef8',
- 'aphront-panel-view-css' => 'a4e76ef8',
- 'aphront-table-view-css' => 'a4e76ef8',
- 'aphront-tokenizer-control-css' => 'a4e76ef8',
- 'aphront-tooltip-css' => 'a4e76ef8',
- 'aphront-typeahead-control-css' => 'a4e76ef8',
+ 'aphront-dialog-view-css' => '30de5267',
+ 'aphront-error-view-css' => '30de5267',
+ 'aphront-list-filter-view-css' => '30de5267',
+ 'aphront-pager-view-css' => '30de5267',
+ 'aphront-panel-view-css' => '30de5267',
+ 'aphront-table-view-css' => '30de5267',
+ 'aphront-tokenizer-control-css' => '30de5267',
+ 'aphront-tooltip-css' => '30de5267',
+ 'aphront-typeahead-control-css' => '30de5267',
'differential-changeset-view-css' => '7cd7e387',
'differential-core-view-css' => '7cd7e387',
'differential-inline-comment-editor' => '5e9e5c4e',
@@ -4536,7 +4536,7 @@
'differential-table-of-contents-css' => '7cd7e387',
'diffusion-commit-view-css' => '270f4eb4',
'diffusion-icons-css' => '270f4eb4',
- 'global-drag-and-drop-css' => 'a4e76ef8',
+ 'global-drag-and-drop-css' => '30de5267',
'inline-comment-summary-css' => '7cd7e387',
'javelin-aphlict' => '6041c6c8',
'javelin-behavior' => '3e3be199',
@@ -4611,56 +4611,56 @@
'javelin-util' => '3e3be199',
'javelin-vector' => '3e3be199',
'javelin-workflow' => '3e3be199',
- 'lightbox-attachment-css' => 'a4e76ef8',
+ 'lightbox-attachment-css' => '30de5267',
'maniphest-task-summary-css' => '49898640',
- 'phabricator-action-list-view-css' => 'a4e76ef8',
- 'phabricator-application-launch-view-css' => 'a4e76ef8',
+ 'phabricator-action-list-view-css' => '30de5267',
+ 'phabricator-application-launch-view-css' => '30de5267',
'phabricator-busy' => '6041c6c8',
'phabricator-content-source-view-css' => '7cd7e387',
- 'phabricator-core-css' => 'a4e76ef8',
- 'phabricator-crumbs-view-css' => 'a4e76ef8',
+ 'phabricator-core-css' => '30de5267',
+ 'phabricator-crumbs-view-css' => '30de5267',
'phabricator-drag-and-drop-file-upload' => '5e9e5c4e',
'phabricator-dropdown-menu' => '6041c6c8',
'phabricator-file-upload' => '6041c6c8',
- 'phabricator-filetree-view-css' => 'a4e76ef8',
- 'phabricator-flag-css' => 'a4e76ef8',
+ 'phabricator-filetree-view-css' => '30de5267',
+ 'phabricator-flag-css' => '30de5267',
'phabricator-hovercard' => '6041c6c8',
- 'phabricator-jump-nav' => 'a4e76ef8',
+ 'phabricator-jump-nav' => '30de5267',
'phabricator-keyboard-shortcut' => '6041c6c8',
'phabricator-keyboard-shortcut-manager' => '6041c6c8',
- 'phabricator-main-menu-view' => 'a4e76ef8',
+ 'phabricator-main-menu-view' => '30de5267',
'phabricator-menu-item' => '6041c6c8',
- 'phabricator-nav-view-css' => 'a4e76ef8',
+ 'phabricator-nav-view-css' => '30de5267',
'phabricator-notification' => '6041c6c8',
- 'phabricator-notification-css' => 'a4e76ef8',
- 'phabricator-notification-menu-css' => 'a4e76ef8',
+ 'phabricator-notification-css' => '30de5267',
+ 'phabricator-notification-menu-css' => '30de5267',
'phabricator-object-selector-css' => '7cd7e387',
'phabricator-phtize' => '6041c6c8',
'phabricator-prefab' => '6041c6c8',
'phabricator-project-tag-css' => '49898640',
- 'phabricator-remarkup-css' => 'a4e76ef8',
+ 'phabricator-remarkup-css' => '30de5267',
'phabricator-shaped-request' => '5e9e5c4e',
- 'phabricator-side-menu-view-css' => 'a4e76ef8',
- 'phabricator-standard-page-view' => 'a4e76ef8',
- 'phabricator-tag-view-css' => 'a4e76ef8',
+ 'phabricator-side-menu-view-css' => '30de5267',
+ 'phabricator-standard-page-view' => '30de5267',
+ 'phabricator-tag-view-css' => '30de5267',
'phabricator-textareautils' => '6041c6c8',
'phabricator-tooltip' => '6041c6c8',
- 'phabricator-transaction-view-css' => 'a4e76ef8',
- 'phabricator-zindex-css' => 'a4e76ef8',
- 'phui-button-css' => 'a4e76ef8',
- 'phui-form-css' => 'a4e76ef8',
- 'phui-form-view-css' => 'a4e76ef8',
- 'phui-header-view-css' => 'a4e76ef8',
- 'phui-icon-view-css' => 'a4e76ef8',
- 'phui-list-view-css' => 'a4e76ef8',
- 'phui-object-item-list-view-css' => 'a4e76ef8',
- 'phui-property-list-view-css' => 'a4e76ef8',
- 'phui-spacing-css' => 'a4e76ef8',
- 'sprite-apps-large-css' => 'a4e76ef8',
- 'sprite-gradient-css' => 'a4e76ef8',
- 'sprite-icons-css' => 'a4e76ef8',
- 'sprite-menu-css' => 'a4e76ef8',
- 'sprite-status-css' => 'a4e76ef8',
- 'syntax-highlighting-css' => 'a4e76ef8',
+ 'phabricator-transaction-view-css' => '30de5267',
+ 'phabricator-zindex-css' => '30de5267',
+ 'phui-button-css' => '30de5267',
+ 'phui-form-css' => '30de5267',
+ 'phui-form-view-css' => '30de5267',
+ 'phui-header-view-css' => '30de5267',
+ 'phui-icon-view-css' => '30de5267',
+ 'phui-list-view-css' => '30de5267',
+ 'phui-object-item-list-view-css' => '30de5267',
+ 'phui-property-list-view-css' => '30de5267',
+ 'phui-spacing-css' => '30de5267',
+ 'sprite-apps-large-css' => '30de5267',
+ 'sprite-gradient-css' => '30de5267',
+ 'sprite-icons-css' => '30de5267',
+ 'sprite-menu-css' => '30de5267',
+ 'sprite-status-css' => '30de5267',
+ 'syntax-highlighting-css' => '30de5267',
),
));
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -1536,6 +1536,9 @@
'PhabricatorRedirectController' => 'applications/base/controller/PhabricatorRedirectController.php',
'PhabricatorRefreshCSRFController' => 'applications/auth/controller/PhabricatorRefreshCSRFController.php',
'PhabricatorRegistrationProfile' => 'applications/people/storage/PhabricatorRegistrationProfile.php',
+ 'PhabricatorRemarkupBlockInterpreterCowsay' => 'infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterCowsay.php',
+ 'PhabricatorRemarkupBlockInterpreterFiglet' => 'infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterFiglet.php',
+ 'PhabricatorRemarkupBlockInterpreterGraphviz' => 'infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterGraphviz.php',
'PhabricatorRemarkupControl' => 'view/form/control/PhabricatorRemarkupControl.php',
'PhabricatorRemarkupRuleEmbedFile' => 'applications/files/remarkup/PhabricatorRemarkupRuleEmbedFile.php',
'PhabricatorRemarkupRuleImageMacro' => 'applications/macro/remarkup/PhabricatorRemarkupRuleImageMacro.php',
@@ -3747,6 +3750,9 @@
'PhabricatorRedirectController' => 'PhabricatorController',
'PhabricatorRefreshCSRFController' => 'PhabricatorAuthController',
'PhabricatorRegistrationProfile' => 'Phobject',
+ 'PhabricatorRemarkupBlockInterpreterCowsay' => 'PhutilRemarkupBlockInterpreter',
+ 'PhabricatorRemarkupBlockInterpreterFiglet' => 'PhutilRemarkupBlockInterpreter',
+ 'PhabricatorRemarkupBlockInterpreterGraphviz' => 'PhutilRemarkupBlockInterpreter',
'PhabricatorRemarkupControl' => 'AphrontFormTextAreaControl',
'PhabricatorRemarkupRuleEmbedFile' => 'PhabricatorRemarkupRuleObject',
'PhabricatorRemarkupRuleImageMacro' => 'PhutilRemarkupRule',
Index: src/infrastructure/markup/PhabricatorMarkupEngine.php
===================================================================
--- src/infrastructure/markup/PhabricatorMarkupEngine.php
+++ src/infrastructure/markup/PhabricatorMarkupEngine.php
@@ -460,6 +460,7 @@
$blocks[] = new PhutilRemarkupEngineRemarkupNoteBlockRule();
$blocks[] = new PhutilRemarkupEngineRemarkupTableBlockRule();
$blocks[] = new PhutilRemarkupEngineRemarkupSimpleTableBlockRule();
+ $blocks[] = new PhutilRemarkupEngineRemarkupInterpreterRule();
$custom_block_rule_classes = $options['custom-block'];
if ($custom_block_rule_classes) {
Index: src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterCowsay.php
===================================================================
--- /dev/null
+++ src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterCowsay.php
@@ -0,0 +1,55 @@
+<?php
+
+final class PhabricatorRemarkupBlockInterpreterCowsay
+ extends PhutilRemarkupBlockInterpreter {
+
+ public function getInterpreterName() {
+ return 'cowsay';
+ }
+
+ public function markupContent($content, array $argv) {
+ if (!Filesystem::binaryExists('cowsay')) {
+ return $this->markupError(
+ pht('Unable to locate the `cowsay` binary. Install cowsay.'));
+ }
+
+ $bin = idx($argv, 'think') ? 'cowthink' : 'cowsay';
+ $eyes = idx($argv, 'eyes', 'oo');
+ $tongue = idx($argv, 'tongue', ' ');
+ $cow = idx($argv, 'cow', 'default');
+
+ // NOTE: Strip this aggressively to prevent nonsense like
+ // `cow=/etc/passwd`. We could build a whiltelist with `cowsay -l`.
+ $cow = preg_replace('/[^a-z.-]+/', '', $cow);
+
+ $future = new ExecFuture(
+ '%s -e %s -T %s -f %s ',
+ $bin,
+ $eyes,
+ $tongue,
+ $cow);
+
+ $future->write($content);
+
+ list($err, $stdout, $stderr) = $future->resolve();
+
+ if ($err) {
+ return $this->markupError(
+ pht(
+ 'Execution of `cowsay` failed:', $stderr));
+ }
+
+
+ if ($this->getEngine()->isTextMode()) {
+ return $stdout;
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'PhabricatorMonospaced remarkup-cowsay',
+ ),
+ $stdout);
+ }
+
+}
Index: src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterFiglet.php
===================================================================
--- /dev/null
+++ src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterFiglet.php
@@ -0,0 +1,40 @@
+<?php
+
+final class PhabricatorRemarkupBlockInterpreterFiglet
+ extends PhutilRemarkupBlockInterpreter {
+
+ public function getInterpreterName() {
+ return 'figlet';
+ }
+
+ public function markupContent($content, array $argv) {
+ if (!Filesystem::binaryExists('figlet')) {
+ return $this->markupError(
+ pht('Unable to locate the `figlet` binary. Install figlet.'));
+ }
+
+ $future = id(new ExecFuture('figlet'))
+ ->write(trim($content, "\n"));
+
+ list($err, $stdout, $stderr) = $future->resolve();
+
+ if ($err) {
+ return $this->markupError(
+ pht(
+ 'Execution of `figlet` failed:', $stderr));
+ }
+
+
+ if ($this->getEngine()->isTextMode()) {
+ return $stdout;
+ }
+
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'PhabricatorMonospaced remarkup-figlet',
+ ),
+ $stdout);
+ }
+
+}
Index: src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterGraphviz.php
===================================================================
--- /dev/null
+++ src/infrastructure/markup/interpreter/PhabricatorRemarkupBlockInterpreterGraphviz.php
@@ -0,0 +1,44 @@
+<?php
+
+final class PhabricatorRemarkupBlockInterpreterGraphviz
+ extends PhutilRemarkupBlockInterpreter {
+
+ public function getInterpreterName() {
+ return 'dot';
+ }
+
+ public function markupContent($content, array $argv) {
+ if (!Filesystem::binaryExists('dot')) {
+ return $this->markupError(
+ pht('Unable to locate the `dot` binary. Install Graphviz.'));
+ }
+
+ $future = id(new ExecFuture('dot -T%s', 'png'))
+ ->write(trim($content));
+
+ list($err, $stdout, $stderr) = $future->resolve();
+
+ if ($err) {
+ return $this->markupError(
+ pht(
+ 'Execution of `dot` failed, check your syntax: %s', $stderr));
+ }
+
+ $file = PhabricatorFile::buildFromFileDataOrHash(
+ $stdout,
+ array(
+ 'name' => 'graphviz.png',
+ ));
+
+ if ($this->getEngine()->isTextMode()) {
+ return '<'.$file->getBestURI().'>';
+ }
+
+ return phutil_tag(
+ 'img',
+ array(
+ 'src' => $file->getBestURI(),
+ ));
+ }
+
+}
Index: webroot/rsrc/css/core/remarkup.css
===================================================================
--- webroot/rsrc/css/core/remarkup.css
+++ webroot/rsrc/css/core/remarkup.css
@@ -329,6 +329,20 @@
border-right: 1px solid #cccccc;
}
+.remarkup-interpreter-error {
+ padding: 8px;
+ border: 1px solid {$red};
+ background-color: {$lightred};
+}
+
+.remarkup-cowsay {
+ white-space: pre-wrap;
+}
+
+.remarkup-figlet {
+ white-space: pre-wrap;
+}
+
.remarkup-assist {
display: block;
width: 14px;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Mar 15, 11:39 PM (1 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7653872
Default Alt Text
D7332.id.diff (13 KB)
Attached To
Mode
D7332: Implement Graphviz, Figlet and Cowsay as Remarkup interpreter blocks
Attached
Detach File
Event Timeline
Log In to Comment