Bitcoin Forum
May 10, 2026, 11:55:44 AM *
News: Latest Bitcoin Core release: 31.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: « 1 [2]  All
  Print  
Author Topic: Adding [nbsp] (non-breaking space) to the BBCode parser (SMF patch)  (Read 768 times)
PowerGlove (OP)
Hero Member
*****
hacker
Offline

Activity: 697
Merit: 7027



View Profile
October 21, 2025, 12:49:25 AM
Merited by LoyceV (12), jayce (1), TheBeardedBaby (1), joker_josue (1), TypoTonic (1)
 #21

(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.
*/

jayce
Legendary
*
Offline

Activity: 3682
Merit: 1622


RIP Condoras 🥀


View Profile WWW
October 21, 2025, 02:10:21 AM
Merited by PowerGlove (1)
 #22

That [r] tag would be a big help in signature design, PowerGlove 💃🕺❤️🎶 Oh and the [nbsp] tag, I have been using it regularly on all of my signature designs. Thank you for the great ideas you have brought to us Cool

Edit: I forgot how to use [nobbc] tag lol.

 
█▄
R


▀▀██████▄▄
████████████████
▀█████▀▀▀█████
████████▌███▐████
▄█████▄▄▄█████
████████████████
▄▄██████▀▀
LLBIT▀█ 
  TH#1 SOLANA CASINO  
████████████▄
▀▀██████▀▀███
██▄▄▀▀▄▄████
████████████
██████████
███▀████████
▄▄█████████
████████████
████████████
████████████
████████████
█████████████
████████████▀
████████████▄
▀▀▀▀▀▀▀██████
████████████
███████████
██▄█████████
████▄███████
████████████
█░▀▀████████
▀▀██████████
█████▄█████
████▀▄▀████
▄▄▄▄▄▄▄██████
████████████▀
........5,000+........
GAMES
 
......INSTANT......
WITHDRAWALS
..........HUGE..........
REWARDS
 
............VIP............
PROGRAM
 .
   PLAY NOW    
rat03gopoh
Legendary
*
Offline

Activity: 2660
Merit: 1010


NO KYC Exchanger☝️


View Profile WWW
October 21, 2025, 06:04:57 AM
Merited by LoyceV (6), TypoTonic (1)
 #23

Edit: I forgot how to use [nobbc] tag lol.
[nobbc]'s alternative while i didn't know this tag existed, ;D 8)

[color=black]Big Black Clock[/color]
Code:
[colo[s][/s]r=black]Big Black Clock[/color]
Each tag available in this forum can actually mess with each other, making them as unknown tags. It also works for messing up emojis like the one above.


I thought nobbc would also ignore previous opened tags if I applied it to the selected text, but it doesn't.
What I expect: lorem ipsum dolor sit amet(nobbc tag opened and closed in the word "dolor sit").
What I got looks like this: lorem ipsum dolor sit amet

 
 b1exch.to 
  ETH      DAI   
  BTC      LTC   
  USDT     XMR    
.███████████▄▀▄▀
█████████▄█▄▀
███████████
███████▄█▀
█▀█
▄▄▀░░██▄▄
▄▀██▄▀█████▄
██▄▀░▄██████
███████░█████
█░████░█████████
█░█░█░████░█████
█░█░█░██░█████
▀▀▀▄█▄████▀▀▀
TypoTonic
Sr. Member
****
Offline

Activity: 294
Merit: 540


'To err is human; to persist is diabolical'


View Profile WWW
October 21, 2025, 11:31:09 AM
 #24

-snip-
I thought nobbc would also ignore previous opened tags if I applied it to the selected text, but it doesn't.
What I expect: lorem ipsum dolor sit amet(nobbc tag opened and closed in the word "dolor sit").
What I got looks like this: lorem ipsum dolor sit amet
This makes sense, no? Since [nobbc] only prevents tags inside it from being parsed, it won't prevent the formatting applied from outside the tag.

██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██



██
██
██
██
██
██
██



██
██
██
██
██



██
██

██
██
██
██
██
██
██
██
██
██
███████▄▄███████▄▄
████▄███████████████▄█████▄▄▄
██▄███████████████████▄▄██▀████▄▄▄▄▄▄▄▄███▄██████
▄███████████████████▀▄█████▄▄███████████▄▀▀▀██▄██
▄███▐███████████████▄▄▀███▀███▄█████████████▄███████
████▐██████████████████▀██▄▀██▐██▄▄▄▄██▀███▀▀███▀▀▀
█████████████████████▌▄▄▄██▐██▐██▀▀▀▀███████████
███████▌█████████▐██████▄▀██▄▀█████████████████████▄
▀██▐███▌█████████▐███▀████████▄██████████▀███████████
▀█▐█████████████████▀▀▀███▀██▀▀▀▀▀▀▀▀▀██▀▀▀███▀▀▀▀▀
██▀███████████████████▀▄██▀
████▀███████████████▀
███████▀▀███████▀▀
██
██


██
██
██
██
██
██
██
██
██

██
██
██


██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
 
   FAST    🔒 SECURE    🛡️ NO KYC    [  EXCHANGE NOW  ]  
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██

██
██
██
██
██
██


██
██
██
██
██
██
██
██
██
██

██
██
██
██
██
██
██
██
██
██
██
LoyceV
Legendary
*
Offline

Activity: 4032
Merit: 21768


Thick-Skinned Gang Leader and Golden Feather 2021


View Profile WWW
October 21, 2025, 11:38:56 AM
 #25

This makes sense, no? Since [nobbc] only prevents tags inside it from being parsed, it won't prevent the formatting applied from outside the tag.
It does, but it would nice to have one tag that closes all previously opened tags. Maybe just [/].

¡uʍop ǝpᴉsdn pɐǝɥ ɹnoʎ ɥʇᴉʍ ʎuunɟ ʞool no⅄
TypoTonic
Sr. Member
****
Offline

Activity: 294
Merit: 540


'To err is human; to persist is diabolical'


View Profile WWW
October 21, 2025, 12:12:58 PM
 #26

This makes sense, no? Since [nobbc] only prevents tags inside it from being parsed, it won't prevent the formatting applied from outside the tag.
It does, but it would nice to have one tag that closes all previously opened tags. Maybe just [/].
There's an alternative that I've learned here for designing signatures which is to close only the parent tag.
Code:
[b][font=Arial][size=9pt][color=green]Lorem ipsum[/b]
Output: Lorem ipsum

But of course we don't always use [b], [i], or [u] so it would actually be nice to have [/].

██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██



██
██
██
██
██
██
██



██
██
██
██
██



██
██

██
██
██
██
██
██
██
██
██
██
███████▄▄███████▄▄
████▄███████████████▄█████▄▄▄
██▄███████████████████▄▄██▀████▄▄▄▄▄▄▄▄███▄██████
▄███████████████████▀▄█████▄▄███████████▄▀▀▀██▄██
▄███▐███████████████▄▄▀███▀███▄█████████████▄███████
████▐██████████████████▀██▄▀██▐██▄▄▄▄██▀███▀▀███▀▀▀
█████████████████████▌▄▄▄██▐██▐██▀▀▀▀███████████
███████▌█████████▐██████▄▀██▄▀█████████████████████▄
▀██▐███▌█████████▐███▀████████▄██████████▀███████████
▀█▐█████████████████▀▀▀███▀██▀▀▀▀▀▀▀▀▀██▀▀▀███▀▀▀▀▀
██▀███████████████████▀▄██▀
████▀███████████████▀
███████▀▀███████▀▀
██
██


██
██
██
██
██
██
██
██
██

██
██
██


██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██
 
   FAST    🔒 SECURE    🛡️ NO KYC    [  EXCHANGE NOW  ]  
██
██
██
██
██
██
██
██
██
██
██
██
██
██
██

██
██
██
██
██
██


██
██
██
██
██
██
██
██
██
██

██
██
██
██
██
██
██
██
██
██
██
Pages: « 1 [2]  All
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!