summaryrefslogtreecommitdiffstats
path: root/vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php')
-rw-r--r--vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php246
1 files changed, 246 insertions, 0 deletions
diff --git a/vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php b/vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php
new file mode 100644
index 0000000..953cb9a
--- /dev/null
+++ b/vendor/jfcherng/php-diff/src/Renderer/AbstractRenderer.php
@@ -0,0 +1,246 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Jfcherng\Diff\Renderer;
+
+use Jfcherng\Diff\Differ;
+use Jfcherng\Diff\SequenceMatcher;
+use Jfcherng\Diff\Utility\Language;
+
+/**
+ * Base class for diff renderers.
+ */
+abstract class AbstractRenderer implements RendererInterface
+{
+ /**
+ * @var array information about this renderer
+ */
+ public const INFO = [
+ 'desc' => 'default_desc',
+ 'type' => 'default_type',
+ ];
+
+ /**
+ * @var bool Is this renderer pure text?
+ */
+ public const IS_TEXT_RENDERER = true;
+
+ /**
+ * @var string[] array of the opcodes and their corresponding symbols
+ */
+ public const SYMBOL_MAP = [
+ SequenceMatcher::OP_DEL => '-',
+ SequenceMatcher::OP_EQ => ' ',
+ SequenceMatcher::OP_INS => '+',
+ SequenceMatcher::OP_REP => '!',
+ ];
+
+ /**
+ * @var Language the language translation object
+ */
+ protected $t;
+
+ /**
+ * If the input "changes" have `<ins>...</ins>` or `<del>...</del>`,
+ * which means they have been processed, then `false`. Otherwise, `true`.
+ *
+ * @var bool
+ */
+ protected $changesAreRaw = true;
+
+ /**
+ * @var array array of the default options that apply to this renderer
+ */
+ protected static $defaultOptions = [
+ // how detailed the rendered HTML in-line diff is? (none, line, word, char)
+ 'detailLevel' => 'line',
+ // renderer language: eng, cht, chs, jpn, ...
+ // or an array which has the same keys with a language file
+ // check the "Custom Language" section in the readme for more advanced usage
+ 'language' => 'eng',
+ // show line numbers in HTML renderers
+ 'lineNumbers' => true,
+ // show a separator between different diff hunks in HTML renderers
+ 'separateBlock' => true,
+ // show the (table) header
+ 'showHeader' => true,
+ // convert spaces/tabs into HTML codes like `<span class="ch sp"> </span>`
+ // and the frontend is responsible for rendering them with CSS.
+ // when using this, "spacesToNbsp" should be false and "tabSize" is not respected.
+ 'spaceToHtmlTag' => false,
+ // the frontend HTML could use CSS "white-space: pre;" to visualize consecutive whitespaces
+ // but if you want to visualize them in the backend with "&nbsp;", you can set this to true
+ 'spacesToNbsp' => false,
+ // HTML renderer tab width (negative = do not convert into spaces)
+ 'tabSize' => 4,
+ // this option is currently only for the Combined renderer.
+ // it determines whether a replace-type block should be merged or not
+ // depending on the content changed ratio, which values between 0 and 1.
+ 'mergeThreshold' => 0.8,
+ // this option is currently only for the Unified and the Context renderers.
+ // RendererConstant::CLI_COLOR_AUTO = colorize the output if possible (default)
+ // RendererConstant::CLI_COLOR_ENABLE = force to colorize the output
+ // RendererConstant::CLI_COLOR_DISABLE = force not to colorize the output
+ 'cliColorization' => RendererConstant::CLI_COLOR_AUTO,
+ // this option is currently only for the Json renderer.
+ // internally, ops (tags) are all int type but this is not good for human reading.
+ // set this to "true" to convert them into string form before outputting.
+ 'outputTagAsString' => false,
+ // this option is currently only for the Json renderer.
+ // it controls how the output JSON is formatted.
+ // see availabe options on https://www.php.net/manual/en/function.json-encode.php
+ 'jsonEncodeFlags' => \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE,
+ // this option is currently effective when the "detailLevel" is "word"
+ // characters listed in this array can be used to make diff segments into a whole
+ // for example, making "<del>good</del>-<del>looking</del>" into "<del>good-looking</del>"
+ // this should bring better readability but set this to empty array if you do not want it
+ 'wordGlues' => ['-', ' '],
+ // change this value to a string as the returned diff if the two input strings are identical
+ 'resultForIdenticals' => null,
+ // extra HTML classes added to the DOM of the diff container
+ 'wrapperClasses' => ['diff-wrapper'],
+ ];
+
+ /**
+ * @var array array containing the user applied and merged default options for the renderer
+ */
+ protected $options = [];
+
+ /**
+ * The constructor. Instantiates the rendering engine and if options are passed,
+ * sets the options for the renderer.
+ *
+ * @param array $options optionally, an array of the options for the renderer
+ */
+ public function __construct(array $options = [])
+ {
+ $this->setOptions($options);
+ }
+
+ /**
+ * Set the options of the renderer to those supplied in the passed in array.
+ * Options are merged with the default to ensure that there aren't any missing
+ * options.
+ *
+ * @param array $options the options
+ *
+ * @return static
+ */
+ public function setOptions(array $options): self
+ {
+ $newOptions = $options + static::$defaultOptions;
+
+ $this->updateLanguage(
+ $this->options['language'] ?? '',
+ $newOptions['language']
+ );
+
+ $this->options = $newOptions;
+
+ return $this;
+ }
+
+ /**
+ * Get the options.
+ *
+ * @return array the options
+ */
+ public function getOptions(): array
+ {
+ return $this->options;
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * @final
+ *
+ * @todo mark this method with "final" in the next major release
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function getResultForIdenticals(): string
+ {
+ $custom = $this->options['resultForIdenticals'];
+
+ if (isset($custom) && !\is_string($custom)) {
+ throw new \InvalidArgumentException('renderer option `resultForIdenticals` must be null or string.');
+ }
+
+ return $custom ?? $this->getResultForIdenticalsDefault();
+ }
+
+ /**
+ * Get the renderer default result when the old and the new are the same.
+ */
+ abstract public function getResultForIdenticalsDefault(): string;
+
+ /**
+ * {@inheritdoc}
+ */
+ final public function render(Differ $differ): string
+ {
+ $this->changesAreRaw = true;
+ // the "no difference" situation may happen frequently
+ return $differ->getOldNewComparison() === 0
+ ? $this->getResultForIdenticals()
+ : $this->renderWorker($differ);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ final public function renderArray(array $differArray): string
+ {
+ $this->changesAreRaw = false;
+
+ return $this->renderArrayWorker($differArray);
+ }
+
+ /**
+ * The real worker for self::render().
+ *
+ * @param Differ $differ the differ object
+ */
+ abstract protected function renderWorker(Differ $differ): string;
+
+ /**
+ * The real worker for self::renderArray().
+ *
+ * @param array[][] $differArray the differ array
+ */
+ abstract protected function renderArrayWorker(array $differArray): string;
+
+ /**
+ * Update the Language object.
+ *
+ * @param string|string[] $old the old language
+ * @param string|string[] $new the new language
+ *
+ * @return static
+ */
+ protected function updateLanguage($old, $new): self
+ {
+ if (!isset($this->t) || $old !== $new) {
+ $this->t = new Language($new);
+ }
+
+ return $this;
+ }
+
+ /**
+ * A shorthand to do translation.
+ *
+ * @param string $text The text
+ * @param bool $escapeHtml Escape the translated text for HTML?
+ *
+ * @return string the translated text
+ */
+ protected function _(string $text, bool $escapeHtml = true): string
+ {
+ $text = $this->t->translate($text);
+
+ return $escapeHtml ? \htmlspecialchars($text) : $text;
+ }
+}