Parseur markdown en PHP

Le problème exposé dans ce sujet a été résolu.

Pourtant ça n'a pas l'air si compliqué que ça.

A essayer avec un callback. Après il faut enlever les barres avec une autre regex mais je pense qu'un truc dans ce goût-là devrait le faire :

1
@\[\[i\]\]\n((?:^\s*\|[^|]+(?:\n|\Z))+)@ms

Perso je parse des listes y compris imbriquées et des tableaux avec des regex dans le genre et ça marche très bien…

+0 -0

Il me semble que Parsedown a encore beaucoup de soucis et n'est pas assez stable pour être utilisé en prod. Le projet est jeune, on ne sait pas trop encore si il va être vraiment maintenu.

En revanche tu as un binding de hoedown via l'extension php-hoedown, tu devrais jeter un oeil à ça ! En plus d'être plus complet c'est bien plus performant. (C'est du C et c'est utilisé par beaucoup de monde donc bien mieux maintenu)

@Kje : c'est aussi possible avec le parseur php que j'ai choisi, mais apparemment ce ne peut être fait que manuellement. Tu as une idée pour automatiser ça ?

elyppire

Bah dans la section Extension: auto_identifiers il explique comment il génère le slug depuis le nom, donc tu peux t'en inspirer. Encore en dessous, il propose aussi une syntaxe pour faire des liens vers ces éléments sans mettre le slug

En fait, j'aimerais au maximum éviter les liens brisés. Pour la doc, je travaille avec des id, je sait que je pointerais toujours vers la bonne doc (sauf si on fait un couper/coller sur une autre doc, mais bon, c'est pas mon problème).

Par contre, si je pouvais éviter qu'un lien vers une partie de la doc se brise pour un mot ajouté, ce serait kewl.

+0 -0

Ce que j'ai fait sur un projet client (pour extraire un sommaire) c'est de lire le HTML une fois le MD parsé et transformé.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<?php

if(!function_exists('extract_toc')){
  function extract_toc($dom, $max_level = 2) {

      $xpath = new DOMXPath($dom);
      $xpath->registerNamespace('html', 'http://www.w3.org/1999/xhtml');
      
      $headings = array('h1', 'h2', 'h3', 'h4', 'h5', 'h6');
      foreach($headings as $k => $v){
          $headings[$k] = 'self::'.$v;
      }
      $query_headings = implode(' or ', $headings);
      $query = '//*['.$query_headings.']';
      $headings = $xpath->query($query);

      $toc = '<ol class="toc-level-1">';

      $current_level = 1;
      $items = 0;

      foreach($headings as $n_i => $node){
          $level = (int) $node->tagName{1};

          if ($level > $max_level) {
              continue;
          }

          $node_id = $node->getAttribute('id');

          if(empty($node_id)){
              $node_id = 'toc_'.url_title(strip_tags($node->textContent), '-', TRUE);
              $node->setAttribute('id', $node_id);
          }

          $new_toc = '<a href="#'.$node_id.'">'.xss_clean($node->textContent).'</a>';

          if($level === $current_level){
              $toc .= ($items ? '</li>' : '').'<li>'.$new_toc;
          }
          elseif($level > $current_level){
              $toc .= '<ol class="toc-level-'.$level.'"><li>'.$new_toc;
          }
          else{
              $toc .= '</li></ol></li><li>'.$new_toc;
          }

          $current_level = $level;
      }

      $toc .= '</li><ol>';

      return $toc;
  }
}

Tu peux t'inspirer de ça en virant éventuellement la génération de HTML. ;)

N.B. : La fonction url_title est propre au framework que j'utilise : elle transforme une string en slug (la | version jolie URL en gros).


[EDIT] Ok, j'avais pas vu l'extension proposée par Kje et ta contrainte d'ID constant… My bad.

Du coup je vois pas trop comment faire à part de les fixer dans le MD (par l'utilisateur ou par un script)

Par contre, si je pouvais éviter qu'un lien vers une partie de la doc se brise pour un mot ajouté, ce serait kewl.

Bah ça je ne vois pas trop d'autres solution qu'un identifiant fait fixé par l'utilisateur. Si tu ne veux pas que l'identifiant soit généré depuis le titre (ce qui casserai en cas de modification du titre), il ne reste plus que le "chemin" vers le titre ("2eme sous-section de la 3eme section") pour l'identifier mais là ça cassera si tu déplace des éléments ou rajoute d'autres sections entre les deux.

Si tu sorts les infos du parseurs, tu peux par contre les recouper et détecter si des liens vers des ancres qui n'existes pas.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte