За последние 24 часа нас посетили 16604 программиста и 1278 роботов. Сейчас ищут 1043 программиста ...

Подсветка синтаксиса

Тема в разделе "Регулярные выражения", создана пользователем Kreker, 16 июн 2009.

  1. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Сколько смотрел простых функций и библиотек - ни одна не понравилась. Поэтому уже очень давно хотел сделать свою, заступорился и забил.
    Сейчас хочу реализовать подсветку на JS. Посмотрел текущие реализации - не понравились. Начал писать свою, но напоролся на проблему.

    Например, возьмем код:

    Код (Text):
    1. require_once 'Zend2.php';
    2.  
    3.   /**
    4.    * @see     getUri()
    5.    */
    6.    $uri = explode(":", $uri, 2);

    По сути дела, подсвечивать необходимо следующее:
    1. Строки
    2. Числа
    3. Операторы
    4. Комментарии
    5. Управляющие конструкции
    6. Переменные

    На первый взгляд все просто. Но если посмотреть глубже - впадаю в ступор.

    1. Допустим, подсвечиваю строки:
    Код (Text):
    1. require_once <span class="string">'Zend2.php'</span>;
    2.  
    3.   /**
    4.    * @see     getUri()
    5.    */
    6.    $uri = explode(<span class="string">":"</span>, $uri, 2);
    2. Подсвечиваю числа
    Код (Text):
    1. require_once <span class="string">'Zend<span class="digit">2</span>.php'</span>;
    2.  
    3.   /**
    4.    * @see     getUri()
    5.    */
    6.    $uri = explode(<span class="string">":"</span>, $uri, <span class="digit">2</span>);
    Как видно, в первой же строке ошибка - число в комментарии подчеркиваться не должно

    3. Подсвечиваю операторы
    Код (Text):
    1. require_once <span class="operator"><</span>span class="string"<span class="operator">></span>'Zend<span class="digit">2</span><span class="operator">.</span>php'</span>;
    2. ...
    ???
     
  2. kostyl

    kostyl Guest

    Не парья возьми готовую либу... Я уже два месяца пишу подсветку. Ты еще не представляешь сколько проблем.
    Могу сразу подсказать. Нужно парсить посимвольно и кусками в перемешку, иначе код типа :
    PHP:
    1.  
    2. <?php
    3. /**
    4. *Привет  мед' "1вед"
    5. */
    6. $this->__toString('asdj"jdslkf', "sadf'asdjl");
    7.  
    тупо заменами, даже с коллбеками не поддастся...
     
  3. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Kreker
    Так пропускать нужно для подсветки контент в кавычках =)
     
  4. kostyl

    kostyl Guest

    И какую интересно простоту ты хочешь? Какие смотрел? PEAR?
    На JS видел одну библу. Принцип: разрисовывает всеми языками, какой больше подойдет - тот и оставляет. Ну это я так к слову о JS.
    Лично я забил на свою реализацию подсветки, ибо все довольно сложно. Даже в том же php. Разрисовать html, а в нем php. Это вобще жесть. Плюс куча всяких моментов.
    Короче остановился на GeSHi. Меня вполне устроило, окромя как ее глюки с mbstring.func_overload > 0. Сейчас парюсь по этому поводу в соседнем топике.
     
  5. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    В принципе, там нужно смотреть, нет ли <span(.*?)>вокруг тегов</span>

    9 Кб - это много. Основная идея хранить - подсчечивать в JS, чтобы не разукрашивать его каждый раз. И JS может сохранить много кб =)
     
  6. kostyl

    kostyl Guest

    Я кэширую и 9 кб только на один раз.
    В принципе? Ну-ну, я буду следить за этим топиком. Или ты мне не доверяешь? ;)
     
  7. kostyl

    kostyl Guest

    Вроде она :)
     
  8. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Регулярка-убийца:
    /\*(.*?)\*/
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Блин, не могу вытащить контент между
    /* */ =)
     
  10. TheShock

    TheShock Активный пользователь

    С нами с:
    30 май 2009
    Сообщения:
    1.255
    Симпатии:
    0
    Адрес:
    Київ
    Может, так?
    Код (Text):
    1. /\/\*(.*?)\*\//
     
  11. kostyl

    kostyl Guest

    C чем путает?
     
  12. kostyl

    kostyl Guest

    А может так?
    Код (Text):
    1.  
    2. /\\/\\*(.*?)\\*\\//
     
  13. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    PHP:
    1. <?
    2.  
    3. $code = "void main()\n{\n\t/* Main Function */\n}\n\n";
    4.  
    5. if(preg_match('{/\*(.*?)\*/}s', $code, $commented_code)) {
    6.     echo $code;
    7.     print_r($commented_code);
    8. }
    9.  
    10. ?>
    Outputs:
    Код (Text):
    1. void main()
    2. {
    3.     /* Main Function */
    4. }
    5.  
    6. Array
    7. (
    8.     [0] => /* Main Function */
    9.     [1] =>  Main Function
    10. )
    Али я не понял)
     
  14. kostyl

    kostyl Guest

    Apple
    Он на JS вроде пишет...
     
  15. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    kostyl
    Эммм .. тогда простите, пойду перепишу под JS :)
     
  16. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    [js]var expr = RegExp('/\\*(.+?)\\*/');
    var comm = expr.exec("void main()\n{\n\t/* Main Function */\n}\n\n");

    document.write(comm[1]);[/js]

    Вот, теперь пойду похаваю :)
     
  17. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    ПыСы:
    В объекте RegExp никаких ограничителей / — нет. В РНР они введены для указания модификаторов, в строковых реализациях JS — тоже, но когда используем объект, модификаторы указываются в качестве второго аргумента.
    Эти я так, ВДРУГ кто не знает.
    Всего лишь вдруг, но это наврядле. :)
     
  18. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Убивает браузер и прогу



    Ничего не выдает! Не пойму, почему (многострочный текст).
     
  19. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Ну это только в объекте. Регулярки можно без объекта делать, а там ограничители нужны.
     
  20. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Конечно сомнительно, но вдруг:

    [js]var expr = RegExp('/\\*(.+?)\\*/', "m");
    var comm = expr.exec("void main()\n{\n\t/* Main Function */\n}\n\n");

    document.write(comm[1]);[/js]

    Я использовать стараюсь только объекты: удобно и практично.
    Можно в студию реальный файл или его часть?
    Прям с ним будем пробовать.
     
  21. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Код (Text):
    1. require_once 'Zend.php';
    2. require_once 'Zend/Uri/Exception.php';
    3. require_once 'Zend/Uri/Http.php';
    4. require_once 'Zend/Uri/Mailto.php';
    5.  
    6. abstract class Zend_Uri
    7. {
    8.  
    9.   /**
    10.    * Return a string representation of this URI.
    11.    *
    12.    * @see     getUri()
    13.    * @return  "string"
    14.    */
    15.   public function __toString()
    16.   {
    17.       return $this->getUri();
    18.   }
    19.  
    20.   /*
    21.   /*
    22.    'bl"a"bla'
    23.    */
    24.    
    25.   static public function factory($uri = 'http')
    26.   {
    27.       $uri = explode(":", $uri, 2);
    28.       $scheme = strtolower($uri[0]);
    29.       $schemeSpecific = isset($uri[1]) ? $uri[1] : '';
    30.     $string = 'LOL"!"';
    31.       // Security check: $scheme is used to load a class file,
    32.       // so only alphanumerics are allowed.
    33.       if (!ctype_alnum($scheme)) {
    34.           throw new Zend_Uri_Exception('Illegal scheme');
    35.       }
    36.   }
    37. }
     
  22. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    Всему виной точка, которая не работает с переносами ...
    Думаем, чем заменить ..

    [js]var expr = RegExp('/\\*([^\x00]+?)\\*/');
    var comm = expr.exec(document.getElementById('code').innerHTML);

    for(i = 0; i < comm.length; i++) {
    alert(comm);
    }[/js]

    Пробуем вписать нулевой символ, который, по-идее, не может присутствовать в тексте.
    Вроде работает корректно, проверял.
     
  23. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Эврика, спасибо!
    var reg = new RegExp('(/\\*((.|\r|\n)*?)\\*\/)', "gi");

    Ага, так и есть!

    Блин, вчера всю ночь потратил с этим :cry:
     
  24. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия