开发者

converting markdown lists to html lists in PHP

I have been working on a markdown converter today for a project of mine. I got lost in it and just ran through the code and noticed I had a huge amount for converting lists. My code is below , I have just supplied the code that deals with lists, I could really do with some suggestions on shortening the code, I just cant see past what I have written and need a fresh pair of eyes.

<?php

class Markdown {

  private static $html = '';
  private static $list_types = array(
    array(
      '>>',
      '<ul>',
      '</ul>'
    ),
    array(
      '>>>',
      '<ol>',
      '</ol>'
    )
  );
  private static $list_patterns = array(
    '/-[ ]+(.+)/' => ' >>\1',
    '/[0-9]{1}\. (.+)/' => ' >>>\1'
  );

  public static function convertText($markdown = array()) {
    $markdown = explode("\n", strip_tags($markdown));
    foreach ($markdown as &$line) {
      $line = htmlentities($line, ENT_QUOTES, 'UTF-8');
      foreach (self::$list_patterns as $pattern => $replace) {
        if (!is_array($line) && preg_match($pattern, $line)) {
          $para = false;
          $line = preg_replace($pattern, $replace, $line);
          $type = 0;
          foreach (self::$list_types as $key => $val) {
            if (preg_match('/ ' . $val[0] . ' /', $line))
              $type = $key;
          }
          $line = preg_split('/' . self::$list_types[$type][0] . '/', $line);
          $line = array('depth' => strlen($line[0]), 'string' => $line[1], 'type' => $type);
        }
      }
    }

    while (!empty($markdown)) {
      $snippet = array_shift($markdown);
      if (is_array($snippet))
        self::makeList($snippet, $markdown);
      else
        self::$html .= $snippet;
    }
    return self::$html;
  }

  private static function makeList($snippet, &$markdown, $last_depth = 0, $close_tag = '') {
    if ($last_depth == $snippet['depth'])
      self::$html .= sprintf('</li><li>%s', $snippet['string']);
    elseif ($last_depth < $snippet['depth'])
      self::$html .= sprintf('%s<li>%s', self::$list_types[$snippet['type']][1], $snippet['string']);
    elseif ($last_depth > $snippet['depth'])
      self::$html .= sprintf('</li>%s<li>%s', $close_tag, $snippet['string']);

    $next_snippet = array_shift($markdown);
    if (is_array($next_snippet))
      self::makeList($next_snippet, $markdown, $snippet['depth'], self::$list_types[$snippet['type']][2]);
    else
      array_unshift($markdown, $next_snippet);

    self::$html .= sprintf('</li>%s', $close_tag);
  }

}

?>

Basically the code does lots of p开发者_运维问答attern matching and for any patterns except list it will leave as a string in the array "$markdown", for lists it creates an array with the list type, depth and string. There fore at the end of the text conversion I can loop through the "$markdown" array and build the nested loop structure by checking if the next item is an array or not.

Sorry if the question seems vague, its not ment to be, I just want some hint on how to shorten my code as it seems like I have written loads.

Thanks in advance

Luke


@Theifmaster is probably a better way forward. But, I managed to remove 2 lines of code, and the unused variable $para;

<?php

class Markdown {

  private static $html = '';
  private static $list_types = array(
    array('>>','<ul>','</ul>'),
    array('>>>','<ol>','</ol>')
  );
  private static $list_patterns = array(
    '/-[ ]+(.+)/' => ' >>\1',
    '/[0-9]{1}\. (.+)/' => ' >>>\1'
  );

  public static function convertText($markdown = array()) {
    foreach (explode("\n", strip_tags($markdown)) as &$line) {
      $line = htmlentities($line, ENT_QUOTES, 'UTF-8');
      foreach (self::$list_patterns as $pattern => $replace) {
        if (!is_array($line) && preg_match($pattern, $line)) {
          $line = preg_replace($pattern, $replace, $line);
          $type = 0;
          foreach (self::$list_types as $key => $val) {
            if (preg_match('/ ' . $val[0] . ' /', $line))
              $type = $key;
          }
          $line = preg_split('/' . self::$list_types[$type][0] . '/', $line);
          $line = array('depth' => strlen($line[0]), 'string' => $line[1], 'type' => $type);
        }
      }
    }

    while (!empty($markdown)) {
      $snippet = array_shift($markdown);
      if (is_array($snippet))
        self::makeList($snippet, $markdown);
      else
        self::$html .= $snippet;
    }
    return self::$html;
  }

  private static function makeList($snippet, &$markdown, $last_depth = 0, $close_tag = '') {
    if ($last_depth == $snippet['depth'])
      self::$html .= sprintf('</li><li>%s', $snippet['string']);
    elseif ($last_depth < $snippet['depth'])
      self::$html .= sprintf('%s<li>%s', self::$list_types[$snippet['type']][1], $snippet['string']);
    elseif ($last_depth > $snippet['depth'])
      self::$html .= sprintf('</li>%s<li>%s', $close_tag, $snippet['string']);

    $next_snippet = array_shift($markdown);
    if (is_array($next_snippet))
      self::makeList($next_snippet, $markdown, $snippet['depth'], self::$list_types[$snippet['type']][2]);
    else
      array_unshift($markdown, $next_snippet);

    self::$html .= sprintf('</li>%s', $close_tag);
  }

}

enjoy


As @Theifmaster said, michelf.com/projects/php-markdown is already comprehensive and awesome so I ended up using it as I really was not going to manage to add anything more useful to it. Good learning experience though starting to write the code.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜