Smartypants - emdash not working

As said in the subject - I enabled smartypants in the config file, but emdash seems not to work, while endash works correctly. This is what I set (config.php):

‘smartypants’ => true,

According to the markdown guide seen on daringfireball.com, smartypants should replace “—” with an emdash.

I’ve seen in an old post (2015) here on the forum a more sophysticated configuration, like

'smartypants.space.emdash' => '  ',

but I couldn’t fine any reference about it on getkirby.com.

Thanks

You can set an array of options in your config:

'smartypants' => [
   'space.emdash'               => ' ',
   'space.endash'               => ' ',
   'space.colon'                => ' ',
]

etc.

I’ll try. But – do you sleep sometimes? :slight_smile:

I cut and paste your code in the config.php file and added the right numeric entities

'smartypants' => [
    'space.emdash'               => '& #151;',
    'space.endash'               => '& #150;'
  ],

but nothing happens. I mean - all the replacements are ok (ellipsis, en dash, etc), but the em dash still doesn’t work. Moreover, it seems that everything I write in the config.php file is ignored.

image

Any hint?

Could you please post your config? Have you made sure that there is only one return statement?

Sure, here you are


<?php

/* 
---------------------------------------
Troubleshooting
---------------------------------------

Kirby has a built-in troubleshooting screen 
with loads of information about your setup.

It's there to help you out when things don't work
as expected. Set it to true to activate it and
go to your homepage afterwards to display it on refresh. 

*/ 

c::set('troubleshoot', true);

/*

---------------------------------------
Debug 
---------------------------------------

Set this to true to enable php errors. 
Make sure to keep this disabled for your 
production site, so you won't get nasty 
php errors there.

*/

c::set('debug', true);

/*
---------------------------------------
Uso di <figure> per renderizzare le immagini 
---------------------------------------
*/
c::set("kirbytext.image.figure", true);


//Paginazione
c::set('hnt.pagesize',5);



/*
---------------------------------------
Routes
---------------------------------------

Kirby will register a new route to http://yoursite.com/logout When you open that URL, 
the action method will be called and if there's a logged in user, 
the user will be logged out. 
Afterwards the script will redirect the user to the login page.

*/


c::set('routes', array(
  
  //login
  array(
    'pattern' => 'logout',
    'action'  => function() {
      if($user = site()->user()) $user->logout();
      go('login');
    } 
  )
  
  //Friendly URL -- tracks
  ,array(
    'pattern' => 'tracks/(:any)/(:any)/(:any)',
    'action' => function($artist, $title, $aid){

      $results = site()->search($aid, 'articleid');

      if ($results->count()>0) {
        go(site()->home() . $results->first(), 301);
      }
    }
  )

  //Friendly URL -- a
  ,array(
    'pattern' => 'a/(:any)',
    'action' => function($aid){

      $results = site()->search($aid, 'articleid');

      if ($results->count()>0) {
        go(site()->home() . $results->first(), 301);
      }
    }
  )

  //Lista articoli
  ,array(
    'pattern' => 'tracks',
    'action' => function(){
      go(site()->home(), 301);
    }
  )

));





return[

  /*
  --------------------------
  Session
  ---------------------------
  */

  'session' => [

    'durationNormal' => 7200, // default: 2 hours
    'durationLong' => 1209600, // default: 2 weeks
    'timeout' => 1800, // default: half an hour
    'cookieName' => 'kirby_session',
    'gcInterval' => 100 // default: cleanup every ~100 requests
  ],



  /*
  --------------------------
  Smartypants
  ---------------------------
 */ 

  'smartypants' => [
    'space.emdash'               => '&#151;',
    'space.endash'               => '&#150;'
  ],


  /*
  --------------------------
  Hooks
  ---------------------------
  */

  'hooks' => [

    //Crea l'articleID e lo scrive sul file
    //-------------------------------------
    'page.create:after' => function ($page) {

          //Se non è un articolo, esce  
          if($page->template() == "article") 
          {
            //Crea l'article ID
            $ID = $page->date()->toDate("Ymd") . '-' . mt_rand(0, 9999999);
            
            //Aggiorna il file
            try { $page->update(array('articleID' => $ID)); } 
            catch(Exception $e) { echo $e; }
          }
      },


     //Scrive su db l'articolo una volta aggiornato  
     //---------------------------------------------
    'page.update:after' => function ($page,$oldpage) {
          
        if($page->template() == "article") 
        {
            //Aggiorna l'articolo su db
            articleUpdate($page);
        }
        elseif ($page->template() == "selezione")
        {
            //Aggiorna la selezione
            saveSelezioneToDB($page);
        }
        elseif ($page->template() == "speciale")
        {
            //Aggiorna l'id dello speciale
            updateArtSpecialID($page);
        }
      },


     //Scrive su db l'articolo quando cambio titolo  
     //---------------------------------------------
    'page.changeTitle:after' => function ($page,$oldpage) {
          
        if($page->template() == "article") 
        {
            //Articoli
            articleUpdate($page);
        }
        elseif ($page->template() == "selezione")
        {
            //Liste
            saveSelezioneToDB($page);
        }
      },


      //Quando cambia il path di uno speciale, 
      //viene cambiato il path di tutti gli articoli che ne fanno parte
      //---------------------------------------------------------------
      'page.changeSlug:after' => function ($page,$oldpage) {

          if($page->template() == "speciale") articleListMove($page);

      },


      //Scrive lo stato della pagina quando passa da invisibile a visibile
      //------------------------------------------------------------------
      'page.changeStatus:after' => function ($page,$oldpage) {
          
          if($page->template() == "article") 
          {
              //Articoli
              articleUpdate($page);
          }
          elseif ($page->template() == "selezione")
          {
              //Liste
              saveSelezioneToDB($page);
          }
      },


      //Elimina un articolo dal db quando viene eliminato dal panel
      //-----------------------------------------------------------
      'page.delete:after' => function ($status, $page) {

        if($page->template() == "article") 
        {
          deleteArticleFromDb($page);
        }
        else if ($page->template() == "selezione")
        {
          deleteSelezioneFromDb($page);
        }

      },


      //Impedisce il salvataggio di alcune specifiche pagine a chi non ha i permessi
      //-----------------------------------------------------------

      'page.update:before' => function ($page, $values, $strings) {
          
        /*if ($page->template() == 'lungo') 
        {
            //Exception
            throw new Exception('Non hai i permessi!');
        }*/
      }


  ]
];



function articleUpdate($page)
{

  $art_artist = "";
  $art_title = "";
  $art_articleID = trim($page->articleID());
  
  //Dal titolo ricava artista e titolo del pezzo e lo scrive sul file
  try{
      $arr = explode(':',$page->title());
      if ($arr[0] > "") $art_artist = trim($arr[0]);
      if ($arr[1] > "") $art_title = trim($arr[1]);
  }
  catch(Exception $e) { echo $e;}

  //Se l'articolo è precedente all'uso del panel, salvo l'articleID generato anche sul file
  if ($art_articleID == "") $art_articleID = $page->uid();

  //Aggiornamento del file
  $page->update(array(
      'artist' => $art_artist, 
      'articleTitle' => $art_title,
      'articleID' => $art_articleID
  ));  

  //Salvataggio su db
  saveArticleToDb($page);
}

The whole first part until the return statement is Kirby 2 syntax, you can’t use that in Kirby 3.

Do you mean - everything before return[… ?

Ok, I took away the old K2 tags.

<?php

return[

  /*
  --------------------------
  Session
  ---------------------------
  */

  'session' => [

    'durationNormal' => 7200, // default: 2 hours
    'durationLong' => 1209600, // default: 2 weeks
    'timeout' => 1800, // default: half an hour
    'cookieName' => 'kirby_session',
    'gcInterval' => 100 // default: cleanup every ~100 requests
  ],



  /*
  --------------------------
  Smartypants
  ---------------------------
 */ 

  'smartypants' => [
    'space.emdash'               => '&#151;',
    'space.endash'               => '&#150;'
  ],


  /*
  --------------------------
  Routes
  ---------------------------
 */ 

 'routes' => [
  
    //Friendly URL -- tracks
    [
      'pattern' => 'tracks/(:any)/(:any)/(:any)',
      'action' => function($artist, $title, $aid){
        $results = site()->search($aid, 'articleid');
        if ($results->count()>0) 
        {
          go(site()->home() . $results->first(), 301);
        }
      }
    ],

    //Friendly URL -- a
    [
      'pattern' => 'a/(:any)',
      'action' => function($aid){
        $results = site()->search($aid, 'articleid');
        if ($results->count()>0) 
        {
          go(site()->home() . $results->first(), 301);
        }
      }
    ],

    //Lista articoli
    [
      'pattern' => 'tracks',
      'action' => function()
      {
        go(site()->home(), 301);
      }
    ]

  ],



  /*
  --------------------------
  Hooks
  ---------------------------
  */

  'hooks' => [

    //Crea l'articleID e lo scrive sul file
    //-------------------------------------
    'page.create:after' => function ($page) {

          //Se non è un articolo, esce  
          if($page->template() == "article") 
          {
            //Crea l'article ID
            $ID = $page->date()->toDate("Ymd") . '-' . mt_rand(0, 9999999);
            
            //Aggiorna il file
            try { $page->update(array('articleID' => $ID)); } 
            catch(Exception $e) { echo $e; }
          }
      },


     //Scrive su db l'articolo una volta aggiornato  
     //---------------------------------------------
    'page.update:after' => function ($page,$oldpage) {
          
        if($page->template() == "article") 
        {
            //Aggiorna l'articolo su db
            articleUpdate($page);
        }
        elseif ($page->template() == "selezione")
        {
            //Aggiorna la selezione
            saveSelezioneToDB($page);
        }
        elseif ($page->template() == "speciale")
        {
            //Aggiorna l'id dello speciale
            updateArtSpecialID($page);
        }
      },


     //Scrive su db l'articolo quando cambio titolo  
     //---------------------------------------------
    'page.changeTitle:after' => function ($page,$oldpage) {
          
        if($page->template() == "article") 
        {
            //Articoli
            articleUpdate($page);
        }
        elseif ($page->template() == "selezione")
        {
            //Liste
            saveSelezioneToDB($page);
        }
      },


      //Quando cambia il path di uno speciale, 
      //viene cambiato il path di tutti gli articoli che ne fanno parte
      //---------------------------------------------------------------
      'page.changeSlug:after' => function ($page,$oldpage) {

          if($page->template() == "speciale") articleListMove($page);

      },


      //Scrive lo stato della pagina quando passa da invisibile a visibile
      //------------------------------------------------------------------
      'page.changeStatus:after' => function ($page,$oldpage) {
          
          if($page->template() == "article") 
          {
              //Articoli
              articleUpdate($page);
          }
          elseif ($page->template() == "selezione")
          {
              //Liste
              saveSelezioneToDB($page);
          }
      },


      //Elimina un articolo dal db quando viene eliminato dal panel
      //-----------------------------------------------------------
      'page.delete:after' => function ($status, $page) {

        if($page->template() == "article") 
        {
          deleteArticleFromDb($page);
        }
        else if ($page->template() == "selezione")
        {
          deleteSelezioneFromDb($page);
        }

      },


      //Impedisce il salvataggio di alcune specifiche pagine a chi non ha i permessi
      //-----------------------------------------------------------

      'page.update:before' => function ($page, $values, $strings) {
          
        /*if ($page->template() == 'lungo') 
        {
            //Exception
            throw new Exception('Non hai i permessi!');
        }*/
      }


  ]
];



function articleUpdate($page)
{

  $art_artist = "";
  $art_title = "";
  $art_articleID = trim($page->articleID());
  
  //Dal titolo ricava artista e titolo del pezzo e lo scrive sul file
  try{
      $arr = explode(':',$page->title());
      if ($arr[0] > "") $art_artist = trim($arr[0]);
      if ($arr[1] > "") $art_title = trim($arr[1]);
  }
  catch(Exception $e) { echo $e;}

  //Se l'articolo è precedente all'uso del panel, salvo l'articleID generato anche sul file
  if ($art_articleID == "") $art_articleID = $page->uid();

  //Aggiornamento del file
  $page->update(array(
      'artist' => $art_artist, 
      'articleTitle' => $art_title,
      'articleID' => $art_articleID
  ));  

  //Salvataggio su db
  saveArticleToDb($page);
}

@hvsrmusic now that you’ve removed all the Kirby2 config code, if you try simply using 'smartypants' => true, it should work.

Try also using the ->smartypants() field method instead of ->kirbytext() or ->kt(). Let us know if it works for you.

@hvsrmusic Still no advance with the modified config?

Note that

a) there shouldn’t be a space
b) an emdash characters as space around an emdash doesn’t really make sense.

To define what an emdash should look like, use emdash not space.emdash

Here are all defaults:

 public function defaults(): array
    {
        return [
            'attr'                       => 1,
            'doublequote.open'           => '&#8220;',
            'doublequote.close'          => '&#8221;',
            'doublequote.low'            => '&#8222;',
            'singlequote.open'           => '&#8216;',
            'singlequote.close'          => '&#8217;',
            'backtick.doublequote.open'  => '&#8220;',
            'backtick.doublequote.close' => '&#8221;',
            'backtick.singlequote.open'  => '&#8216;',
            'backtick.singlequote.close' => '&#8217;',
            'emdash'                     => '&#8212;',
            'endash'                     => '&#8211;',
            'ellipsis'                   => '&#8230;',
            'space'                      => '(?: | |&nbsp;|&#0*160;|&#x0*[aA]0;)',
            'space.emdash'               => ' ',
            'space.endash'               => ' ',
            'space.colon'                => '&#160;',
            'space.semicolon'            => '&#160;',
            'space.marks'                => '&#160;',
            'space.frenchquote'          => '&#160;',
            'space.thousand'             => '&#160;',
            'space.unit'                 => '&#160;',
            'guillemet.leftpointing'     => '&#171;',
            'guillemet.rightpointing'    => '&#187;',
            'geresh'                     => '&#1523;',
            'gershayim'                  => '&#1524;',
            'skip'                       => 'pre|code|kbd|script|style|math',
        ];
    }

That should not be neccessary, because the bug where it only worked with smartypants() was fixed.