Question: commonmark-attributes-extension Add attribute to <pre> tag? #631
-
Hi, '''typescript
console.log('test');
'''
{:data-line="1"} I tried the above but like I said it adds it to a Thank you for PHP CommanMark, love it! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Hey @rob4226,
The custom attributes get applied to the The "info string" is usually added to the This means that, without any customization on your end, the library unfortunately won't support what you want. But the good news is that you can customize this library :) One possible solution would be decorating the core final class MyCustomFencedCodeRenderer implements BlockRendererInterface
{
private FencedCodeRenderer $coreRenderer;
public function __construct(FencedCodeRenderer $coreRenderer)
{
$this->coreRenderer = $coreRenderer;
}
public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
{
// Have the core FencedCodeRenderer do its usual rendering
$preBlock = $this->coreRenderer->render($block, $htmlRenderer, $inTightList);
$codeBlock = $x->getContents(false);
// This "if" statement should always evaluate to true, but we include it for extra type safety
if ($codeBlock instanceof HtmlElement && $codeBlock->getTagName() === 'code') {
if (($line = $codeBlock->getAttribute('data-line')) !== null) {
$preBlock->setAttribute('data-line', $line);
}
}
return $preBlock;
}
} You can then replace the core renderer with this one: $environment->addBlockRenderer(FencedCode::class, new MyCustomFencedCodeRenderer(new FencedCodeRenderer)); Something like that. It's not the simplest solution but I think it should work for you. Alternatively, perhaps you could do something on the JS side to move that attribute before the syntax highlighter is invoked? That might be easier, but I don't know enough about PrismJS to know how feasible that is. I hope that helps!
Thanks, I appreciate that :) |
Beta Was this translation helpful? Give feedback.
-
@colinodell Thank you very much for the response! I will give the decorator a try once I get a chance bc I would prefer to have this done server side. In the meantime I ended up writing some TypeScript to switch the attribute from the window.addEventListener('load', (_ev: Event) => {
const dataLineEls = (document.querySelectorAll(
'[data-line]'
) as unknown) as HTMLElement[];
dataLineEls.forEach((codeEl) => {
const parent = codeEl.parentElement;
if (parent?.tagName === 'PRE') {
parent.setAttribute('data-line', codeEl.getAttribute('data-line') ?? '');
codeEl.removeAttribute('data-line');
}
});
// Neat trick I devised after looking through PrismJS's source code to
// re-render the syntax highlighting. This is necessary bc the above attribute
// switch occurs after Prism is loaded so this in effect reruns that process
// by dispatching a `resize` event.
const trickResizeEvent = new Event('resize');
window.dispatchEvent(trickResizeEvent);
}); |
Beta Was this translation helpful? Give feedback.
-
Hello. I use Winter CMS v1.2.3 and CommonMark [2.4.0] and I really need this feature to highlight lines in a code block. I'm not good at programming. Unfortunately, I didn’t understand how to include this code, I need to replace the contents of the file
If it’s not difficult, tell me in more detail how to do this? Finally, how to use it? I would be very grateful, thanks in advance for your help. |
Beta Was this translation helpful? Give feedback.
Hey @rob4226,
The custom attributes get applied to the
FencedCode
block in our AST. When it's time to render that block, theFencedCodeRenderer
produces the nested<pre><code>...</code></pre>
HTML. The challenge here is that we have Markdown block being converted into two nested HTML elements, so we must pick one of those HTML elements to contain the attributes.The "info string" is usually added to the
<code>
block, since most syntax highlighters expect it to be there, so we decided that any other attributes should also be applied to the<code>
block and not the<pre>
block.This means that, without any customization on your end, the …