Valid XHTML multi-paragraph blockquotes in MT
Last fall when Jeff Szymona posted four MTMacro macros to correct MT’s p tag wrappage around blank line-delimited blockquote tags — which breaks XHTML 1.0 validation — I immediately started using them and they solved my validation problem.
But now as I implement backshaded multi-paragraph blockquotes, I find I need a little more filtering.
I’ve been wrapping each paragraph of a multi-paragraph blockquote with its own blockquote tags. But this makes CSS styling of the blockquote as a contiguous block difficult. And adding the extra blockquote tags has been a hassle.
Here’s what’s correct according to the W3C:
<blockquote cite="http://www.example.com/tolkien/twotowers.html">
<p>They went in single file, running like hounds on a strong scent, and an eager light was in their eyes. Nearly due west the broad swath of the marching Orcs tramped its ugly slot; the sweet grass of Rohan had been bruised and blackened as they passed.</p>
</blockquote>
That is, the blockquote element needs to contain one or more block-level elements, not bare text (the cite attribute is optional).
Here’s what I want to enter (with a quick copy and paste):
<blockquote>The rain in Spain falls mainly in the plain. The rain in Spain falls mainly in the plain.
The rain in Spain falls mainly in the plain. The rain in Spain falls mainly in the plain.</blockquote>
Here’s how I want MT to render it:
<blockquote><p>The rain in Spain falls mainly in the plain. The rain in Spain falls mainly in the plain.</p>
<p>The rain in Spain falls mainly in the plain. The rain in Spain falls mainly in the plain.</p></blockquote>
I created three additional macros to supplement Jeff’s, and AFAICT they’re meeting this goal. All seven macros in a clean text snippet here.
Jeff’s original macros:
<MTMacroDefine name="pdiv1" pattern="m/<p\x3e<div/"><div</MTMacroDefine>
<MTMacroDefine name="pdiv2" pattern="m/<\/div\x3e<\/p/"></div</MTMacroDefine>
<MTMacroDefine name="pbq1" pattern="m/<p\x3e<blockquote/"><blockquote</MTMacroDefine>
<MTMacroDefine name="pbq2" pattern="m/<\/blockquote\x3e<\/p/"></blockquote</MTMacroDefine>
My three additional ones:
<MTMacroDefine name="pbq3" pattern="m/<blockquote\x3e(?!(<p\x3e|\r))/"><blockquote><p></MTMacroDefine>
<MTMacroDefine name="pbq4" pattern="m/(?<!<\/p\x3e)<\/blockquote\x3e/"></p></blockquote></MTMacroDefine>
<MTMacroDefine name="pbq5" pattern="m/(?<!\x3e)\s*\n\n\n*<p\x3e/"></p><p></MTMacroDefine>
Alas, I’m no Friedl; I think it’s the negative lookbehind assertion in my pbq4 macro that slurps clock cycles. If you see a more efficient solution, please comment.
I see I really need to start using the blockquote element’s cite attribute. Brad even provides code to automatically make the citation a visible link in the blockquote.
Here’s what the new macros are doing:
pbq3: from `perldoc perlre` —
/foo(?!bar)/ ("foo" not followed by "bar")
I want "<blockquote>" not followed by "<p>" or "\r".
find replace /<blockquote>(?!(<p>|\r))/ <blockquote><p> straight Perl regex /<blockquote\x3e(?!(<p\x3e|\r))/ <blockquote><p> encoded for MTMacro use
<MTMacroDefine name="pbq3" pattern="m/<blockquote\x3e(?!(<p\x3e|\r))/"><blockquote><p></MTMacroDefine>
pbq4: from `perldoc perlre` —
/(?<!bar)foo/ ("foo" that does not follow "bar")
I want "</blockquote> that does not follow "</p>".
find replace /(?<!</p>)</blockquote>/ </p></blockquote> straight Perl regex /(?<!<\/p\x3e)<\/blockquote\x3e/ </p></blockquote> encoded for MTMacro use
<MTMacroDefine name="pbq4" pattern="m/(?<!<\/p\x3e)<\/blockquote\x3e/"></p></blockquote></MTMacroDefine>
pbq5: from `perldoc perlre` —
/(?<!bar)foo/ ("foo" that does not follow "bar")
I want "\n\n\n*" that does not follow ">" (to insert line-end </p> instances that MT seems to have missed).
find replace (?<!>)\n\n\n*<p> </p>\n\n<p> straight Perl regex (?<!\x3e)\n\n\n*<p\x3e </p>\n\n<p> encoded for MTMacro use
<MTMacroDefine name="pbq5" pattern="m/(?<!\x3e)\s*\n\n\n*<p\x3e/"></p><p></MTMacroDefine>
I’m not sure how to enter returns in an MTMacro pattern macro replace. (Neither "\n\n" nor "\\n\\n" works.) The emitted HTML would be more cosmetically pleasing if two returns were present between the previous line’s </p> and <p>.