Topic 5440501
Merits
⭐ Merited by LoyceV (12) ,jayce (1) ,TypoTonic (1) ,TheBeardedBaby (1) ,joker_josue (1)
(Trying to tie up loose ends.)

Re-reading this thread reminded me of the [r] tag that I worked on to help out jayce (and other signature designers).

I never got around to properly testing/finishing it, and I don't see me now finding the time/energy to do that, so I figured I should at least dump the last diff I made in case anyone ever wants to pick this one up:

Code:
--- /var/www/baseline/Sources/Subs.php 2011-09-17 21:59:55.000000000 +0000
+++ /var/www/modified/Sources/Subs.php 2023-06-01 16:35:10.000000000 +0000
@@ -1465,24 +1465,48 @@
  'block_level' => true,
  ),
  array(
  'tag' => 'quote',
  'parameters' => array(
  'author' => array('match' => '(.{1,192}?)', 'validate' => 'parse_bbc'),
  ),
  'before' => '<div class="quoteheader">' . $txt['smf239'] . ': {author}</div><div class="quote">',
  'after' => '</div>',
  'block_level' => true,
  ),
  array(
+ 'tag' => 'r',
+ 'type' => 'unparsed_equals_content',
+ 'content' => '$1',
+ 'disabled_content' => '[r=$2]$1[/r]',
+ 'test' => '\d{1,3}\]',
+ 'validate' => function(&$tag, &$data, &$disabled) {
+ // Don't do anything if the tag has been disabled (just rely on 'disabled_content', above).
+ if(isset($disabled['r']))
+ return;
+ // Self-nesting won't work (the first encountered [/r] will close the outermost [r]) for this type of tag (unparsed_equals_content), so detect it and output '(r:nesting)' instead.
+ // This also (conveniently) saves me from having to think too deeply about accidentally introducing recursion-related security issues.
+ if(strpos($data[0], '[r=') !== false) {
+ $data[0] = '(r:nesting)';
+ return;
+ }
+ $count = (int)$data[1];
+ // Skip parsing if the result won't end up contributing to the output.
+ $parsed = $count > 0 ? parse_bbc($data[0]) : '';
+ // Seems prudent (considering the intended use cases for this tag) to enforce a conservative size limit, and output '(r:overflow)' when that limit is exceeded.
+ // If you replace str_repeat() with something else, then make sure to verify that the $count == 0 case is being handled correctly.
+ $data[0] = strlen($parsed) * $count <= 256 ? str_repeat($parsed, $count) : '(r:overflow)';
+ },
+ ),
+ array(
  'tag' => 'right',
  'before' => '<div style="text-align: right;">',
  'after' => '</div>',
  'block_level' => true,
  ),
  array(
  'tag' => 'red',
  'before' => '<span style="color: red;">',
  'after' => '</span>',
  ),
  array(
  'tag' => 'rtl',

Because I suspect (or more like know at this point) that most of you are not going to carefully (re-)read the thread, I'll remind you what the [r] tag (that the above diff is for) does: it's intended as a way to (non-recursively, with respect to itself) parse and then "repeat" (a given number of times) the BBCode that it wraps.

So, if you're designing a signature, and you, for example, wanted a 32-character "bar", then instead of typing:

░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░

You'd type:

[r=32]░[/r]

It's tough to appreciate (and orthogonal to its intended purpose), but, one of the really cool things about this tag is that it (accidentally) forms a pretty natural way to add "comments" to BBCode. As in, if you ask it to repeat something zero times, then you'll have a construct that persists within the BBCode of a post/PM/signature, but one that won't survive the translation into (X)HTML:

[r=0]Made by jayce[/r]

Now, there are a few obvious and not-so-obvious uses for BBCode comments, and the use case I was getting excited about back in 2023 was the one where comments could be used to embed "directives" within posts/PMs/signatures. For example, work stalled on my thread banners idea when I realized that instead of adding new UI elements and new database columns, I could get the whole idea to work (and some other ideas, too) by defining a little "directive language" and specifying the banner-specifics with a BBCode comment (placed anywhere in the opening post of a topic).

I'm not going to unpack the whole thing now, but, perhaps this old PM will shed some light on what I had in mind:

Just sharing some thoughts I had (about the directive parser) while walking the dog.

We could base it on XML, like this (i.e. a prefix, and then ordinary XML):

[r=0]@:<threadBanner text="..." fgColor="#000" bgColor="#FFF" until="1685577599" />[/r]

I'm not sure what the XML situation in PHP is like, but I'm assuming it's all based on libxml2, and that's a lot of additional attack surface to expose.

We could also base it on S-expressions (I've written one or two embeddable lisps), but I think that might be a bit too weird for most people.

We could base it on JSON, I suppose, but same as with XML, I don't really feel like writing my own implementation, and I don't feel like combing through a ton of someone else's code to vouch for its safety.

I think something like what I proposed earlier will work out nicely, especially if we simplify it so that it only accepts strings as arguments, like this:

[r=0]@:threadBanner(text="...", fgColor="#000", bgColor="#FFF", until="1685577599")[/r]

That way, the pattern is {prefix}{identifier}{openRoundBracket}{arguments}{closeRoundBracket}, and {arguments} is a comma-separated sequence of {identifier}{equalsSign}{stringLiteral}.

That should admit a very straightforward parser that spits out an associative array, like this: ["@:cmd" => "threadBanner", "fgColor" => "#000", "bgColor" => "#FFF", "until" => "1685577599"].

Call me mad, but I would trust 30 lines of PHP that we've both looked at carefully, much more than any shifting dependency.

I was never able to convince theymos that this approach made sense (compared to, for example, implementing the "thread banners" idea in the obvious way: by emitting some new UI elements on the action=post page, and having them affect and be affected by some new database columns).

I think the last thought I had about this before I put the whole thing to bed was to maybe break out a "comment" tag as its own thing instead of convolving it with a "repeat" tag (as in, a "repeat" tag is a difficult/complex thing to think through and justify adding, but I didn't want months/years of hemming and hawing to block the "comment" use case). Probably I'd name that tag [rem] (for "remark"), which should ring a distant bell for anyone that's ever done much BASIC (or batch file) programming.

And that's all I have to say about that. Wink





While I'm on the subject of "code comments", this one cracked me up pretty good:

//
// Dear maintainer:
//
// Once you are done trying to 'optimize' this routine,
// and have realized what a terrible mistake that was,
// please increment the following counter as a warning
// to the next guy:
//
// total_hours_wasted_here = 42
//


Cheesy Cheesy Cheesy

This one, too:

/**
* For the brave souls who get this far: You are the chosen ones,
* the valiant knights of programming who toil away, without rest,
* fixing our most awful code. To you, true saviors, kings of men,
* I say this: never gonna give you up, never gonna let you down,
* never gonna run around and desert you. Never gonna make you cry,
* never gonna say goodbye. Never gonna tell a lie and hurt you.
*/