diff --git a/packages/guides-restructured-text/src/RestructuredText/Directives/CodeBlockDirective.php b/packages/guides-restructured-text/src/RestructuredText/Directives/CodeBlockDirective.php index 056604b30..f47cd07e6 100644 --- a/packages/guides-restructured-text/src/RestructuredText/Directives/CodeBlockDirective.php +++ b/packages/guides-restructured-text/src/RestructuredText/Directives/CodeBlockDirective.php @@ -10,7 +10,9 @@ use phpDocumentor\Guides\RestructuredText\Parser\BlockContext; use phpDocumentor\Guides\RestructuredText\Parser\Directive; use phpDocumentor\Guides\RestructuredText\Parser\DirectiveOption; +use Psr\Log\LoggerInterface; +use function preg_match; use function trim; /** @@ -26,8 +28,13 @@ */ class CodeBlockDirective extends BaseDirective { - public function __construct(private readonly CodeNodeOptionMapper $codeNodeOptionMapper) - { + /** @see https://regex101.com/r/I3KttH/1 */ + public const LINE_NUMBER_RANGES_REGEX = '/^\d+(-\d+)?(?:,\s*\d+(-\d+)?)*$/'; + + public function __construct( + private readonly LoggerInterface $logger, + private readonly CodeNodeOptionMapper $codeNodeOptionMapper, + ) { } public function getName(): string @@ -58,6 +65,7 @@ public function process( $this->setStartingLineNumberBasedOnOptions($directive->getOptions(), $node); $this->setCaptionBasedOnOptions($directive->getOptions(), $node); + $this->setEmphasizeLinesBasedOnOptions($blockContext, $directive->getOptions(), $node); $this->codeNodeOptionMapper->apply($node, $directive->getOptions()); if ($directive->getVariable() !== '') { @@ -101,4 +109,19 @@ private function setCaptionBasedOnOptions(array $options, CodeNode $node): void $node->setCaption($caption); } + + /** @param DirectiveOption[] $options */ + private function setEmphasizeLinesBasedOnOptions(BlockContext $blockContext, array $options, CodeNode $node): void + { + $emphasizeLines = null; + if (isset($options['emphasize-lines'])) { + $emphasizeLines = (string) $options['emphasize-lines']->getValue(); + if (!preg_match(self::LINE_NUMBER_RANGES_REGEX, $emphasizeLines)) { + // Input does not fit the pattern, log a warning + $this->logger->warning('Invalid value for option emphasize-lines in code-block directive. Expected format: \'1-5, 7, 33\'', $blockContext->getLoggerInformation()); + } + } + + $node->setEmphasizeLines($emphasizeLines); + } } diff --git a/packages/guides-restructured-text/tests/unit/Parser/Productions/DirectiveRuleTest.php b/packages/guides-restructured-text/tests/unit/Parser/Productions/DirectiveRuleTest.php index 297190c4d..01237d3c0 100644 --- a/packages/guides-restructured-text/tests/unit/Parser/Productions/DirectiveRuleTest.php +++ b/packages/guides-restructured-text/tests/unit/Parser/Productions/DirectiveRuleTest.php @@ -103,7 +103,7 @@ public function testCodeBlockValue(string $input, string $expectedValue): void $this->givenInlineMarkupRule(), new Logger('test'), new GeneralDirective(new DirectiveContentRule(new RuleContainer())), - [$this->directiveHandler, new CodeBlockDirective(new CodeNodeOptionMapper())], + [$this->directiveHandler, new CodeBlockDirective(new Logger('test'), new CodeNodeOptionMapper())], ); $context = $this->createContext($input); $node = $this->rule->apply($context); diff --git a/packages/guides/resources/template/html/body/code.html.twig b/packages/guides/resources/template/html/body/code.html.twig index e78e65aa3..47f603fa3 100644 --- a/packages/guides/resources/template/html/body/code.html.twig +++ b/packages/guides/resources/template/html/body/code.html.twig @@ -7,5 +7,7 @@
{%- endif -%} -{{ node.value }}
+ {{ node.value }}
{%- endif -%}
diff --git a/packages/guides/src/Nodes/CodeNode.php b/packages/guides/src/Nodes/CodeNode.php
index 7bedbfa0f..dd86ebfc5 100644
--- a/packages/guides/src/Nodes/CodeNode.php
+++ b/packages/guides/src/Nodes/CodeNode.php
@@ -22,6 +22,8 @@ class CodeNode extends TextNode
private string|null $caption = null;
+ private string|null $emphasizeLines = null;
+
/** @param string[] $lines */
public function __construct(array $lines, protected string|null $language = null)
{
@@ -57,4 +59,14 @@ public function setCaption(string|null $caption): void
{
$this->caption = $caption;
}
+
+ public function getEmphasizeLines(): string|null
+ {
+ return $this->emphasizeLines;
+ }
+
+ public function setEmphasizeLines(string|null $emphasizeLines): void
+ {
+ $this->emphasizeLines = $emphasizeLines;
+ }
}
diff --git a/tests/Integration/tests/code/code-block-emphasize/expected/index.html b/tests/Integration/tests/code/code-block-emphasize/expected/index.html
new file mode 100644
index 000000000..ef6bf853a
--- /dev/null
+++ b/tests/Integration/tests/code/code-block-emphasize/expected/index.html
@@ -0,0 +1,19 @@
+
+
+
+ def some_function():
+ interesting = False
+ print('This line is highlighted.')
+ print('This one is not...')
+ print('...but this one is.')
+