Skip to content
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
18 changes: 16 additions & 2 deletions src/Extension/SemanticSpanExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* - `kbd` attribute → `<kbd>` (keyboard input)
* - `dfn` attribute → `<dfn>` (definition/term)
* - `abbr` attribute → `<abbr>` (abbreviation, with title)
* - `samp` attribute → `<samp>` (sample output)
* - `var` attribute → `<var>` (variable)
*
* These can also be combined, with `dfn` wrapping inner elements.
*
Expand Down Expand Up @@ -67,16 +69,20 @@ public function register(DjotConverter $converter): void
$kbd = $node->getAttribute('kbd');
$dfn = $node->getAttribute('dfn');
$abbr = $node->getAttribute('abbr');
$samp = $node->getAttribute('samp');
$var = $node->getAttribute('var');

// Check if any semantic attribute is present
if ($kbd === null && $dfn === null && $abbr === null) {
if ($kbd === null && $dfn === null && $abbr === null && $samp === null && $var === null) {
return;
}

// Remove semantic attributes from node (they're processed, not rendered)
$node->removeAttribute('kbd');
$node->removeAttribute('dfn');
$node->removeAttribute('abbr');
$node->removeAttribute('samp');
$node->removeAttribute('var');

// Get remaining attributes for outer wrapper
$remainingAttrs = $node->getAttributes();
Expand All @@ -85,14 +91,22 @@ public function register(DjotConverter $converter): void
$content = $event->getChildrenHtml();

// Build inner content with semantic elements
// Priority: abbr innermost, kbd, dfn outermost
// Priority: abbr innermost, then samp/var, then kbd, dfn outermost
$html = $content;

// Wrap in <abbr> if abbr attribute present (with title)
if ($abbr !== null && $abbr !== '') {
$html = '<abbr title="' . StringUtil::escapeHtml((string)$abbr) . '">' . $html . '</abbr>';
}

if ($samp !== null) {
$html = '<samp>' . $html . '</samp>';
}

if ($var !== null) {
$html = '<var>' . $html . '</var>';
}

// Wrap in <kbd> if kbd attribute present
if ($kbd !== null) {
$html = '<kbd>' . $html . '</kbd>';
Expand Down
23 changes: 23 additions & 0 deletions tests/TestCase/Extension/SemanticSpanExtensionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,29 @@ public function testAllThreeCombined(): void
$this->assertStringContainsString('<dfn><kbd><abbr title="HyperText Markup Language">HTML</abbr></kbd></dfn>', $html);
}

public function testSampAttribute(): void
{
$html = $this->converter->convert('[Hello World]{samp}');

$this->assertStringContainsString('<samp>Hello World</samp>', $html);
$this->assertStringNotContainsString('<span samp="">', $html);
}

public function testVarAttribute(): void
{
$html = $this->converter->convert('[x]{var}');

$this->assertStringContainsString('<var>x</var>', $html);
$this->assertStringNotContainsString('<span var="">', $html);
}

public function testCombinedSampAndVar(): void
{
$html = $this->converter->convert('[value]{samp var}');

$this->assertStringContainsString('<var><samp>value</samp></var>', $html);
}

public function testWithoutExtension(): void
{
$converter = new DjotConverter();
Expand Down
Loading