Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Fixing mismatched BBCode
« Reply #15, on December 5th, 2011, 07:37 PM »
I can see the logic of that but I can also see the desire to use code tags inside a code tag... Though that's not practical or really feasible since proper full nesting can't be done anyway. Sounds like a plan to me really.
When we unite against a common enemy that attacks our ethos, it nurtures group solidarity. Trolls are sensational, yes, but we keep everyone honest. | Game Memorial

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #16, on December 5th, 2011, 08:12 PM »
I'm guessing that if you're gonna use the code tag inside another, you'll want to add a matching closer, and since this one'll break the whole block, you'll add a space somewhere to break the closer instead... So might as well wanna break the opener as well with a space. Anyway...

Here's the code, for those interested. It seems to work, at least on my test cases. Maybe you can figure out a faster/shorter way to do it ;)

Code: [Select]
// Find all code blocks, and ensure they follow the [ code][ /code] syntax closely.
if (preg_match_all('~\[(/?)code[^]]*]~i', $message, $matches))
{
$pos = 0;
$tags = array();
foreach ($matches[0] as $id => $tag)
{
$tag_pos = strpos($message, $tag, $pos);
$length = strlen($tag);
$tags[] = array($tag_pos, $length, $matches[1][$id] === '/');
$pos = $tag_pos + $length;
}
$was_closed = true;
$offset = 0;
foreach ($tags as $tag)
{
if ($was_closed === $tag[2]) // consecutive closing tags, or closing tag at the beginning?
{
$message = substr($message, 0, $tag[0] + $offset) . substr($message, $tag[0] + $tag[1] + $offset);
$offset -= $tag[1];
}
$was_closed = $tag[2];
}
if (!$tag[2]) // no final closing tag?
$message .= '[ /code]';
}

(Of course, the irony is that I had to add a space to the tags... :whistle:)

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Fixing mismatched BBCode
« Reply #17, on December 5th, 2011, 08:36 PM »
And you'd have to otherwise, no?

Looks good to me at a first glance.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #18, on December 6th, 2011, 08:24 AM »
AND.... Interestingly, the same code can be reused for proper quote de-nesting :)
Re: Fixing mismatched BBCode
« Reply #19, on December 6th, 2011, 12:21 PM »
Quote from Nao on December 6th, 2011, 08:24 AM
AND.... Interestingly, the same code can be reused for proper quote de-nesting :)
Oh, not that much actually... Because we'd need to remove the contents as well... And improperly nested quotes would then be a nightmare.

Which makes me think... I've often seen cases of people (including me, TBH) surrounding quotes with two closers instead of an opener and a closer. I'm trying to figure out a way to fix these automatically, but honestly it's hard to tell... :-/

PantsManUK

  • [me=PantsManUK]would dearly love to dump SMF 1.X at this juncture...[/me]
  • Posts: 174
Re: Fixing mismatched BBCode
« Reply #20, on December 6th, 2011, 12:49 PM »
Quote from Nao on December 6th, 2011, 12:21 PM
Which makes me think... I've often seen cases of people (including me, TBH) surrounding quotes with two closers instead of an opener and a closer. I'm trying to figure out a way to fix these automatically, but honestly it's hard to tell... :-/
Top of my head, thinking out loud... Count openers and closers, if they match Success!, if they don't, Fail!. Haven't thought beyond that point... leave it with me...  :eheh:

UPDATE: If they don't match, check that the closer count if an odd number, find the first closer *after* the last valid closer and make it an opener, rinse, repeat...
« What is this thing you hoomans call "Facebook"? »

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #21, on December 6th, 2011, 07:11 PM »
Actually, that's a very good suggestion you know...?
I probably wouldn't 'look' for the exact position of the offender, if only because that would mean writing a UI for it (:P) when I can just use SMF's post error box, but it's definitely something of a good idea: we could go through the list of bbcodes that expect a closer tag, and make sure they're there. If not, post an error message asking the user to fix it...
I guess for long posts it's going to be a pain to fix, but OTOH it's only going to be better because if a quote tag is broken and you don't fix it, you're upsetting all of your users. Better one person than everyone...! ;)

:edit: Go through all bbcodes except for those of the 'closed' type... Simple!
Re: Fixing mismatched BBCode
« Reply #22, on December 6th, 2011, 10:33 PM »
Woohoo, this is messy...

Okay, I've finished implementing the checks. It works flawlessly :) Just needs to be optimized... Like, adding a cache for tags.
Unfortunately, Wedge/SMF isn't cooperating. In the sense that it doesn't allow posts to show more than one error of the same type... I'd *love* to know the logic behind that!

Here's what it does:
- Post2 generates an error. Later on, it will fill in $context['post_error']['messages'] with the errors, and $context['post_error'] with the error types.
- Then it calls Post() in Post to regenerate the original form.
- Post(), in turn, EMPTIES $context['post_error']['messages'][1] and attempts to regenerate it based on the error types...
Which means that not only do we lose any additional errors of the same type (it only generates only error message for each type), but we also lose any customizations done in Post2... That's ridiculous.

Now, logic dictates that I 'simply' get rid of the current Post() code and instead use the same code as in Post2. But the code is really shitty in Post()... I mean, there's only one possible error set BEFORE we re-parse 'post_error'. The only other reason to re-parse it, is because Wedge has detected we're previewing or editing a post, i.e. maybe we're coming from Post2... Look at the way the 'no_name' error is handled. In Post2, it's a string added to the list of errors. Then it's handled within the error parser. Then we go back to Post(), where this isn't done until we reach the error parser. At this point, the loop is actually doing the guest tests AGAIN, and adding 'no_name' directly to the list of parsed errors (instead of errors to parse), and... Oh well, it's hard to explain.
Suffice to say, it's really, really really fucked up. I'm so annoying, I'm actually going to let it go for tonight. And I really have no idea how to best handle all of this...
Pete? Any suggestions?
 1. Actually, it starts by emptying $context['post_errors'] (note the plural) which is never used, meaning it's actually a typo...

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Fixing mismatched BBCode
« Reply #23, on December 6th, 2011, 10:38 PM »
Well, the logic behind it is that you should only ever be receiving one instance of any given type of error. I can imagine any circumstance where - normally - you'd need multiple instances of the same message. Wouldn't you just format an otherwise generic message to include all the problem cases?

Remember that the post code - in that context - can be called from both Post2 and directly, and quite possibly other places that don't occur to me right now.

I'm not arguing that it's fucked up, but I'm not sure it's as fucked up as it might be.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #24, on December 6th, 2011, 10:48 PM »
Look at Post2 -- if errors are found, we're ALWAYS redirected to Post().
The messages array is filled in Post2, and ALWAYS reset in Post().

Conclusion: the messages array is filled for no reason in Post2() when it should be done in Post().

That's why I'm upset -- coz I'm gonna have to move my code to Post() tomorrow... -_-

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Fixing mismatched BBCode
« Reply #25, on December 6th, 2011, 10:55 PM »
Oh, I see what you're getting at, misread it at first.

What I was saying is that IIRC there are circumstances where we end up at the post page, not at a creation step, and without having gone to Post2.

Also, Post2 is not the only place content updates are done (quick edit for example)

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #26, on December 6th, 2011, 10:58 PM »
Quote from Arantor on December 6th, 2011, 10:55 PM
Oh, I see what you're getting at, misread it at first.
Mostly because my post was confusing, though...
Quote
Also, Post2 is not the only place content updates are done (quick edit for example)
When it comes to post errors, it shouldn't set them, anyway.

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278
Re: Fixing mismatched BBCode
« Reply #27, on December 6th, 2011, 11:19 PM »
Well, either it should set them and Post should use them, or only Post should be setting them.

Most of the point of Post2 doing anything like that is simply so that there will be something to force it back to Post, but if you're going to rip it out, make sure that there is some way not only to feed back to Post when there's a problem but that it can be extended by plugins too.

Nao

  • Dadman with a boy
  • Posts: 16,082
Re: Fixing mismatched BBCode
« Reply #28, on December 7th, 2011, 07:46 PM »
Quote from Nao on December 5th, 2011, 08:12 PM
Here's the code, for those interested. It seems to work, at least on my test cases. Maybe you can figure out a faster/shorter way to do it ;)
So... Now that Post2 does some proper checking on tags to find mismatched occurrences (and it works very well), do you think there's a point in keeping my improved mismatched code tag fixer in?

PRO: well, it'll make things a bit faster...?
CON: if adding code tags inside anything that does NOT go through Post2 (e.g. an AeMe comment, etc.), it won't work...

Obviously, for anything that does NOT do proper error checking on post contents, it's going to be harder to manage... It's not like we can easily plug these situations into Post2...

Arantor

  • As powerful as possible, as complex as necessary.
  • Posts: 14,278