преобразование списков уценки в списки html в PHP


Сегодня я работал над конвертером уценки для своего проекта. Я заблудился в этом, просто пробежал код и заметил, что у меня есть огромная сумма для преобразования списков. Мой код приведен ниже, я только что предоставил код, который имеет дело со списками, мне действительно не помешали бы некоторые предложения по сокращению кода, я просто не могу видеть дальше того, что я написал, и мне нужна свежая пара глаз.

<?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);
  }

}

?>

В основном код выполняет множество сопоставлений с образцами и для любых шаблонов, кроме списка он оставит в виде строки в массиве "$markdown", для списков он создает массив с типом списка, глубиной и строкой. Поэтому в конце преобразования текста я могу выполнить цикл по массиву "$markdown" и построить структуру вложенного цикла, проверив, является ли следующий элемент массивом или нет.

Извините, если вопрос кажется расплывчатым, его не должно быть, я просто хочу получить подсказку о том, как сократить мой код, поскольку кажется, что я написал много.

Заранее благодарю

Лука

Author: Nicole, 2010-12-01

2 answers

@Theifmaster, вероятно, лучший путь вперед. Но мне удалось удалить 2 строки кода и неиспользуемую переменную $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);
  }

}

Наслаждайтесь

 2
Author: mattclegg, 2012-06-18 13:39:58

Как сказал @Theifmaster, michelf.com/projects/php-markdown уже является всеобъемлющим и потрясающим, поэтому я решил использовать его, так как на самом деле не собирался добавлять к нему ничего более полезного. Хороший опыт обучения, хотя и начинаю писать код.

 0
Author: Luke, 2012-06-08 15:57:17