--- /dev/null
+<?php
+
+/*
+ * This file is part of the Behat.
+ * (c) Konstantin Kudryashov <ever.zet@gmail.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Behat\Behat\Output\Node\Printer\Helper;
+
+use Behat\Gherkin\Node\ExampleNode;
+use Behat\Gherkin\Node\ScenarioLikeInterface as Scenario;
+use Behat\Gherkin\Node\StepNode;
+
+/**
+ * Calculates width of scenario. Width of scenario = max width of scenario title and scenario step texts.
+ *
+ * @author Konstantin Kudryashov <ever.zet@gmail.com>
+ */
+final class WidthCalculator
+{
+ /**
+ * Calculates scenario width.
+ *
+ * @param Scenario $scenario
+ * @param integer $indentation
+ * @param integer $subIndentation
+ *
+ * @return integer
+ */
+ public function calculateScenarioWidth(Scenario $scenario, $indentation, $subIndentation)
+ {
+ $length = $this->calculateScenarioHeaderWidth($scenario, $indentation);
+
+ foreach ($scenario->getSteps() as $step) {
+ $stepLength = $this->calculateStepWidth($step, $indentation + $subIndentation);
+ $length = max($length, $stepLength);
+ }
+
+ return $length;
+ }
+
+ /**
+ * Calculates outline examples width.
+ *
+ * @param ExampleNode $example
+ * @param integer $indentation
+ * @param integer $subIndentation
+ *
+ * @return integer
+ */
+ public function calculateExampleWidth(ExampleNode $example, $indentation, $subIndentation)
+ {
+ $length = $this->calculateScenarioHeaderWidth($example, $indentation);
+
+ foreach ($example->getSteps() as $step) {
+ $stepLength = $this->calculateStepWidth($step, $indentation + $subIndentation);
+ $length = max($length, $stepLength);
+ }
+
+ return $length;
+ }
+
+ /**
+ * Calculates scenario header width.
+ *
+ * @param Scenario $scenario
+ * @param integer $indentation
+ *
+ * @return integer
+ */
+ public function calculateScenarioHeaderWidth(Scenario $scenario, $indentation)
+ {
+ $indentText = str_repeat(' ', intval($indentation));
+
+ if ($scenario instanceof ExampleNode) {
+ $header = sprintf('%s%s', $indentText, $scenario->getTitle());
+ } else {
+ $title = $scenario->getTitle();
+ $lines = explode("\n", $title);
+ $header = sprintf('%s%s: %s', $indentText, $scenario->getKeyword(), array_shift($lines));
+ }
+
+ return mb_strlen(rtrim($header), 'utf8');
+ }
+
+ /**
+ * Calculates step width.
+ *
+ * @param StepNode $step
+ * @param integer $indentation
+ *
+ * @return integer
+ */
+ public function calculateStepWidth(StepNode $step, $indentation)
+ {
+ $indentText = str_repeat(' ', intval($indentation));
+
+ $text = sprintf('%s%s %s', $indentText, $step->getKeyword(), $step->getText());
+
+ return mb_strlen($text, 'utf8');
+ }
+}