php-textile icon indicating copy to clipboard operation
php-textile copied to clipboard

Smileys not welcome in Textile

Open eliph opened this issue 12 years ago • 13 comments

I've just noted that it may not be a good idea to use smileys :-) more than once, because this may result in strikeout :-).

The sentence after Textile parsing:

I’ve just noted that it may not be a good idea to use smileys :) more than once, ‘cause it may result in strikeouts :).

Conversion to ☺ (the unicode character #9786) would prevent this rare phenomenon, but not so important at all.

eliph avatar Dec 30 '12 21:12 eliph

Hi Eliph, thanks for reporting this. If I can fix this easily I will, otherwise I'll look at adding a text smiley->glyph textplug when textplugs are added to the core.

netcarver avatar Dec 31 '12 19:12 netcarver

@netcarver

Hi Steve We have issues with Smilies which have a nose! Textile 2.4.3 seems to do fine, but with 3.5.5 there are some flaws, with: :'( :-) :-| :-O :-( 8-) :-D :-P ;-). The first, fifth, sixt and last do not get parsed and are stricted out. I guess there must be some masquerade happening, which has no return to origin entry. Please note: If our emoticate plugin is happening first, it breaks all multiple smiley appearances with 3.5.5.

ophian avatar Jan 02 '14 17:01 ophian

@ophian Ian, I took a quick look at this last night and have a quick fix that you can try. It probably won't be going into the core without further consideration as it alters the behaviour of all spans for cases where the span is preceded by a colon or semi-colon.

On to the fix: just extend class Parser to override spans() with the following and you should find that smileys have a happier time...

<?php

use Netcarver\Textile\Parser;

class SmileyParser extends Parser
{
    protected function spans($text)
    {
        $span_tags = array_keys($this->span_tags);
        $pnct = ".,\"'?!‹›«»„“”‚‘’";
        $this->span_depth++;

        if ($this->span_depth <= $this->max_span_depth) {
            foreach ($span_tags as $tag) {
                $tag = preg_quote($tag);
                    $text = preg_replace_callback(
                    "/
                    (?P<pre>^|(?<=[\s>$pnct\(])|[{[])
                    (?P<tag>$tag)(?!$tag)
                    (?P<atts>{$this->cls})
                    (?!$tag)
                    (?::(?P<cite>\S+[^$tag]{$this->regex_snippets['space']}))?
                    (?P<content>[^{$this->regex_snippets['space']}$tag]+|\S.*?[^\s$tag\n])
                    (?P<end>[$pnct]*)
                    $tag
                    (?P<tail>$|[\[\]}<]|(?=[$pnct:;]{1,2}[^0-9]|\s|\)))
                    /x".$this->regex_snippets['mod'],
                    array(&$this, "fSpan"),
                    $text
                );
            }
        }
        $this->span_depth--;
        return $text;
    }
}

netcarver avatar Jan 03 '14 09:01 netcarver

Uh fantastic, thanks! Well, I have to figure out how to include this extend class right, but I can say by now, this inside fix is working well for all noses, ie :- or ;-, but not for the very first smiley.

ophian avatar Jan 03 '14 12:01 ophian

@ophian You'd need to add something like this to your new class file to get that first nose fixed...

protected function prepGlyphs()
{
    parent::prepGlyphs();
    array_unshift($this->glyph_search, "/:'([)(])/".$this->regex_snippets['mod']);
    array_unshift($this->glyph_replace, ":'\$1");
}

The above is untested but should mean that :') and :'( remain untouched. NB. This change will break textile's single character curly quoting of any bracketed strings ending in a colon - Avoid ('blended frogs:') where possible.

netcarver avatar Jan 03 '14 14:01 netcarver

Thank you, Steve!

I get preg_replace(): No ending delimiter ':' found in /path/to/lib3/src/Netcarver/Textile/Parser.php on line 3861 and lots of preg_replace_callback(): Compilation failed: invalid UTF-8 string at offset 45 in /path/to/classSmiley.php on line 30 errors.

It looks like encoding stuff is making trouble, but if I change your tweaks in the origin method without SmileyParser, it works. Do you have any ideas what might be the issue or how to get me on the right track?

Cheers

ophian avatar Jan 03 '14 19:01 ophian

@ophian My mistake, I've updated my code example above that should fix your ending delimiter troubles. Care to update and try it again?

netcarver avatar Jan 03 '14 19:01 netcarver

Yepp, the ending delimiter is gone, but it still breaks with lots of preg_replace_callback(): Compilation failed: invalid UTF-8 string at offset 45 in classSmiley.php on line 30

ophian avatar Jan 04 '14 08:01 ophian

@ophian Sorry for the delay in replying. I've updated the post above for a third try.

netcarver avatar Jan 04 '14 20:01 netcarver

Steve, I am sorry to say it is not in prepGlyphs(), as I tried to say before. It is produced in cloned method spans($text). If I change to $pnct = ".,\"'?!‹›«»„“”‚‘’"; and (?P<tail>$|[\[\]}<]|(?=[$pnct:;]{1,2}[^0-9]|\s|\))) in parent (Parser) class and don't clone this method, it works without errors. This is weird, since it doesn't make any sense to me. But this sadly is my experience. I can't even say where that offset 45 happens in preg_replace_callback.

ophian avatar Jan 05 '14 10:01 ophian

Steve, I think I got it! These errors and this clone thing made me crazy and took me to the wild, until I found our emoticate plugin being the cause of all things. It converted to smiley images including an alt tag, holding the human readable, non escaped special emoticate chars. I now made an exception for textile, to just hold the smileys name in there instead and that was it, I hope! Thanks for your friendly help on this. On my behalf this issue may be set to closed.

ophian avatar Jan 05 '14 19:01 ophian

@ophian Glad to hear you managed to resolve your issue. I will leave this issue open for now as we still need to be able to handle this easily in forthcoming releases.

netcarver avatar Jan 05 '14 21:01 netcarver

Yeah better do so, since I was a little bit too quick. This strange clone error still happens (if not editing the origin spans() method), if the emoticate plugin is parsed after textile made its work.

ophian avatar Jan 06 '14 12:01 ophian