Smartypants non brakable space french guillemets

Hi,
I’m trying to configure smartypants for french typosettings. I cannot manage to add non-breakable space to guillemets. I tried to replace them by simple quote to see if smartypants worked and it did, but when I try to add   or   to my script isn’t replace the space by the non breakable ones.

herre my code :

smartypants'=>[ 
    	'attr'  => 1,
    	'doublequote.open'  => '« ',
    	'doublequote.close'  => ' »',
        'space.doublequote' => ' ',
    	'space.emdash'  => ' ',
    	'space.endash'  => ' ',
    	'space.colon'  => ' ',
    	'space.semicolon'  => ' ',
    	'space.marks' => ' ',
    	'space.frenchquote' => ' ',
    	'space.thousand' => '',
    	'space.unit'=> ' ',
        'guillemet.leftpointing'     => '« ',
        'guillemet.rightpointing'    => ' »',
        'geresh'=> '׳',
        'geresh' => '׳',
        'gershayim'=> '״',
        'skip'=> 'pre|code|kbd|script|style|math',
  ]

What’s the leading semicolon doing there in both instances?

Oups an error in copy paste code

don’t know if it’s the right way to add nbsp to guillemets

Hey, I still not manage to have non breakables space before and after french guillemets. Is it possible with the smartypants to configure that ?
thanks

I think the whole idea of the Smartypants parser is to replace ascii characters, not characters, that are already entered correctly as they should be, just to enforce that users add the space. So it only works if you enter << instead of « etc (but the << don’t work in markdown because they have their own function):

Ok, I understand

I think Smartypants might replace straight quotes in strings like Salut "les copains" with the configured quotes, resulting in something like Salut «&nbsp;les copains&nbsp;» with your configuration.

But if the original text is Salut « les copains » it will probably not touch it at all.

On one project I’ve used my own PHP code to do string replacements to transform specific normal spaces into non-breaking spaces:

function nbsp($text) {
    $nbsp = "\u{A0}";
    $text = preg_replace('/(«) /', "$1$nbsp", $text);
    $text = preg_replace('/ (\?|\!|;|:|»)/', "$nbsp$1", $text);
    return $text;
}

echo nbsp($page->content()->text()->value);

Not a super complete implementation of French typographic rules, and it does not add a space when there was none, but it does avoid the vast majority of dangling punctuation. You can always tweak the code if you’re comfortable with regular expressions (and test on something like https://regexr.com/ if not).

I think if you run Smartypants first to transform straight quotes to French quotes, and then do your custom string replacements as shown above, then you’d have good results regardless of if the input uses straight quotes or French quotes with normal spaces.

PS: in my code I use the Unicode value for a non-breaking space, which can be written as \u{A0} in PHP strings (but only in double-quoted strings, not in single-quoted strings). You can also type a non-breaking space directly in your code editor (e.g. with Alt+Space on macOS), but that can be harder to understand when reviewing code because not all code editors will show that it’s different from a normal space. I recommend not using HTML character entities like &nbsp; in your Smartypants config or your string replacements if you can avoid it, because you may want to use the result in contexts that don’t always support HTML character entities: outputting text in HTML attributes and reusing them as text values in JavaScript, outputting titles in RSS or Atom feeds, in JSON data, etc.