Continuing work on extending Parsedown.
Adding block-level elements is not much different from adding inline elements. Kavanot.name originally used <footer>
elements to indicate the source of a block quote:
<blockquote>
Do or do not. There is no try.
</blockquote>
<footer>Yoda</footer>
</blockquote>
While marking blockquotes this way is now acceptable, for a long time it wasn't, and the recommended way was with <figure> and <figcaption>
. KavanotParsedown uses the latter model:
<figure>
<blockquote>
Do or do not. There is no try.
<figcaption>Yoda</figcaption>
<figure>
But I start with creating a <footer>
and then modifying the DOM. So I want to have a block element that I will indicate with "--"
at the start of the line.
function __construct(){
$this->BlockTypes['-'][] = 'Source'; // only line needed to indicate a block level element
// ... rest of the constructor
}
protected function blockSource($Line, $Block = null){
if (preg_match('/^--[ ]*(.+)/', $Line['text'], $matches)) {
return array(
'element' => array(
'name' => 'footer',
'handler' => array(
'function' => 'lineElements',
'argument' => $matches[1],
'destination' => 'elements'
),
'attributes' => array('class' => 'source') // for styling, add a class automatically
)
);
}
}
so
>Do or do not. There is no try.
--Yoda
becomes
<blockquote>
Do or do not. There is no try.
<footer class="source" >Yoda</footer>
</blockquote>
I realized that I might want to add an attribution to an image as well, without it being in a <blockquote>
, as
<p>
<img src=/blog/blogfiles/pdf/smiley.png alt="Smile!"/>
<footer class="source" >Some file I found on the web</footer>
</p>
But as it stands,
[Smile!](/blog/blogfiles/pdf/smiley.png)
--Some file I found on the web
doesn't work; the <p>
ends before the <footer>
starts:
<p>
<img src=/blog/blogfiles/pdf/smiley.png alt="Smile!"/>
</p>
<footer class="source" >Some file I found on the web</footer>
so we need to check that the previous block wasn't a paragraph. If it was, then parse this line and add it to the paragraph as an internal element:
protected function blockSource($Line, $Block = null){
if (preg_match('/^--[ ]*(.+)/', $Line['text'], $matches)) {
if ($Block && $Block['type'] === 'Paragraph'){
$Block['element']['handler']['argument'] .= "\n".$this->element($this->blockSource($Line)['element']);
return $Block;
}
return array(
'element' => array(
'name' => 'footer',
'handler' => array(
'function' => 'lineElements',
'argument' => $matches[1],
'destination' => 'elements'
),
'attributes' => array('class' => 'source') // for styling, add a class automatically
)
);
}
}
and now it works, except that the footer is a child of the <p>
instead of the <blockquote>
. We'll have to fix that.
iambrennanwalsh says:
These “Extending Parsedown” tutorials are incredibly helpful! Besides the bad examples provided in the GitHub repositories wiki, your blog seems to be the only source of documentation I can find on the topic. So thank you! Maybe the author should consider linking to these articles on the Github wiki.
September 21, 2020, 11:06 amDanny says:
Thanks for the feedback! I write that kind of tutorial to teach myself how to understand other people’s programs. Glad that it could help someone else.
September 23, 2020, 8:41 pm