Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE] Support emphasize-lines in code-block directive #690

Merged
merged 1 commit into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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
Expand Down Expand Up @@ -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() !== '') {
Expand Down Expand Up @@ -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();
linawolf marked this conversation as resolved.
Show resolved Hide resolved
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion packages/guides/resources/template/html/body/code.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
<span class="caption-text">{{ node.caption }}</span>
</div>
{%- endif -%}
<pre{% if node.classes %} class="{{ node.classesString }}"{% endif %}><code class="language-{{ node.language }}{{ node.startingLineNumber ? ' line-numbers' }}" {%- if node.startingLineNumber %} data-start="{{ node.startingLineNumber }}"{% endif %}>{{ node.value }}</code></pre>
<pre{% if node.classes %} class="{{ node.classesString }}"{% endif %}><code class="language-{{ node.language }}{{ node.startingLineNumber ? ' line-numbers' }}"
{%- if node.startingLineNumber %} data-start="{{ node.startingLineNumber }}"{% endif -%}
{%- if node.emphasizeLines %} data-emphasize-lines="{{ node.emphasizeLines }}"{% endif -%}>{{ node.value }}</code></pre>
{%- endif -%}
12 changes: 12 additions & 0 deletions packages/guides/src/Nodes/CodeNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>

</head>
<body>
<div class="section" id="title">
<h1>Title</h1>

<pre><code class="language-python" data-emphasize-lines="3,5">def some_function():
interesting = False
print(&#039;This line is highlighted.&#039;)
print(&#039;This one is not...&#039;)
print(&#039;...but this one is.&#039;)</code></pre>
</div>

</body>
</html>
11 changes: 11 additions & 0 deletions tests/Integration/tests/code/code-block-emphasize/input/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Title
=====

.. code-block:: python
:emphasize-lines: 3,5

def some_function():
interesting = False
print('This line is highlighted.')
print('This one is not...')
print('...but this one is.')