Выделение синтаксиса исходников для хабратопиков

    Добрый день.

    Прежде всего, хотелось бы поблагодарить w999d за инвайт :) В ответ захотелось сделать для хабрачан что-то приятное :)

    Когда я писал свой первый пост на Хабре в песочницу, я обратил внимание, что Хабр по какой-то загадочной для меня причине не поддерживает тег выделения синтаксиса для постов. Когда пишешь какую-нибудь статью по программированию, исходник нужно форматировать обязательно, иначе его просто читать никто не будет. Тогда я как-то обошелся каким-то сторонним форматтером, работа которого для PHP кода меня не сильно устроила. Но в мою голову запала мысль сделать нормальный форматтер для хабрачан. Впрочем, даже если окажется, что я изобрел велосипед, время, которое я провел, разбираясь с исходником форматтера, точно не потрачено зря.


    Итак, представляю самую что ни на есть альфа версию HabraSyntax форматтера: http://habrasyntax.fractalizer.ru

    После форматирования, получается примерно следующее:

    <?php
    /*======================================================================*\
    || #################################################################### ||
    || # vBulletin 3.7.3
    || # ---------------------------------------------------------------- # ||
    || # Copyright ©2000-2008 Jelsoft Enterprises Ltd. All Rights Reserved. ||
    || # This file may not be redistributed in whole or significant part. # ||
    || # ---------------- VBULLETIN IS NOT FREE SOFTWARE ---------------- # ||
    || # www.vbulletin.com | www.vbulletin.com/license.html # ||
    || #################################################################### ||
    \*======================================================================
    */

    // ####################### SET PHP ENVIRONMENT ###########################
    error_reporting(E_ALL & ~E_NOTICE);

    // #################### DEFINE IMPORTANT CONSTANTS #######################
    define('THIS_SCRIPT', 'ajax');
    define('CSRF_PROTECTION', true);
    define('LOCATION_BYPASS', 1);
    define('NOPMPOPUP', 1);

    // ################### PRE-CACHE TEMPLATES AND DATA ######################
    // get special phrase groups
    $phrasegroups = array('posting');
    switch ($_POST['do'])
    {
        case 'fetchuserfield':
        case 'saveuserfield':
            $phrasegroups[] = 'cprofilefield';
            $phrasegroups[] = 'user';
    }

    // get special data templates from the datastore
    $specialtemplates = array('bbcodecache');

    // pre-cache templates used by all actions
    $globaltemplates = array();

    // pre-cache templates used by specific actions
    $actiontemplates = array(
        'fetchuserfield' => array(
            'memberinfo_customfield_edit',
            'userfield_checkbox_option',
            'userfield_optional_input',
            'userfield_radio',
            'userfield_radio_option',
            'userfield_select',
            'userfield_select_option',
            'userfield_select_multiple',
            'userfield_textarea',
            'userfield_textbox',
        )
    );

    $_POST['ajax'] = 1;

    // ######################### REQUIRE BACK-END ############################
    require_once('./global.php');
    require_once(DIR . '/includes/class_xml.php');

    // #######################################################################
    // ######################## START MAIN SCRIPT ############################
    // #######################################################################

    ($hook = vBulletinHook::fetch_hook('ajax_start')) ? eval($hook) : false;

    // #############################################################################
    // user name search

    if ($_POST['do'] == 'usersearch')
    {
        $vbulletin->input->clean_array_gpc('p', array('fragment' => TYPE_STR));

        $vbulletin->GPC['fragment'] = convert_urlencoded_unicode($vbulletin->GPC['fragment']);

        if ($vbulletin->GPC['fragment'] != '' AND strlen($vbulletin->GPC['fragment']) >= 3)
        {
            $fragment = htmlspecialchars_uni($vbulletin->GPC['fragment']);
        }
        else
        {
            $fragment = '';
        }

        $xml = new vB_AJAX_XML_Builder($vbulletin, 'text/xml');
        $xml->add_group('users');

        if ($fragment != '')
        {
            $users = $db->query_read_slave("
                SELECT userid, username FROM
    " . TABLE_PREFIX . "user
                WHERE username LIKE('
    " . $db->escape_string_like($fragment) . "%')
                ORDER BY username
                LIMIT 15
            
    ");
            while ($user = $db->fetch_array($users))
            {
                $xml->add_tag('user', $user['username'], array('userid' => $user['userid']));
            }
        }

        $xml->close_group();
        $xml->print_xml();
    }
    Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.


    Поскольку, код только написан, замечания и комментарий приветствуются.

    Поддерживается достаточное количество языков программирования, так что… :) Приятной работы.

    Комментарии 16

      +1
      пока из подсвечивалок мне больше всего нравится s-c.me, там и ссылки на исходник и номера строк и разный формат для хабра/блога
        0
        Спасибо, посмотрю :)
        0
        Ошибка вылазит. Язык — C#.

        Catchable fatal error: Argument 1 passed to GeSHiSingleCharContext::setEscapeCharacters() must be an array, string given, called in /home/fabrik/habrasyntax/public_html/geshi/geshi/languages/csharp/common.php on line 214 and defined in /home/fabrik/habrasyntax/public_html/geshi/geshi/classes/class.geshisinglecharcontext.php on line 89
          0
          Да, видел. Мне понадобилось реализовать собственный рендерер для Geshi. А его можно сделать только начиная с 1.1.2. А он пока в Alpha состоянии. Там еще багов достаточно. Попробую связаться с разработчиком.
            0
            Пофиксил выделение синтаксиса для C#.
          +2
          Что ж неизвестному-то? У вас в профиле и написано, как вы сюда попали по приглашению w999d.
            0
            Да, уже увидел :)
            0
            А можно добавить поддержку xml/xslt? :)
              0
              А вы HTML подсветку юзайте :) Или недостаточно?
                0
                <xsl:for-each select="fb:description/fb:title-info/fb:coverpage/fb:image">
                        <div align="center">
                            <img border="1">
                                <xsl:choose>
                                    <xsl:when test="starts-with(@xlink:href,'#')">
                                        <xsl:attribute name="src"><xsl:text>data:</xsl:text><xsl:variable name="href" select="substring-after(@xlink:href,'#')" /><set variable="href" expression="substring-after(@xlink:href,'#')"/><xsl:value-of select="//fb:binary[@id=$href]/@content-type" disable-output-escaping="yes" /><xsl:text>;base64,</xsl:text><xsl:value-of select="//fb:binary[@id=$href]" disable-output-escaping="yes"/></xsl:attribute>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:attribute name="src"><xsl:value-of select="@xlink:href"/></xsl:attribute>
                                    </xsl:otherwise>
                                </xsl:choose>
                            </img>
                        </div>
                        </xsl:for-each>
                Этот исходный код отформатирован с помощью FractalizeR's HabraSyntax Source Code Highlighter.


                Copy Source | Copy HTML
                1. <xsl:for-each select="fb:description/fb:title-info/fb:coverpage/fb:image">
                2.         <div align="center">
                3.             <img border="1">
                4.                 <xsl:choose>
                5.                     <xsl:when test="starts-with(@xlink:href,'#')">
                6.                         <xsl:attribute name="src"><xsl:text>data:</xsl:text><xsl:variable name="href" select="substring-after(@xlink:href,'#')" /><set variable="href" expression="substring-after(@xlink:href,'#')"/><xsl:value-of select="//fb:binary[@id=$href]/@content-type" disable-output-escaping="yes" /><xsl:text>;base64,</xsl:text><!--<xsl:value-of select="substring-after(@xlink:href,'#')"/>--><xsl:value-of select="//fb:binary[@id=$href]" disable-output-escaping="yes"/></xsl:attribute>
                7.                     </xsl:when>
                8.                     <xsl:otherwise>
                9.                         <xsl:attribute name="src"><xsl:value-of select="@xlink:href"/></xsl:attribute>
                10.                     </xsl:otherwise>
                11.                 </xsl:choose>
                12.             </img>
                13.         </div>
                14.         </xsl:for-each>

                вот ваш и вот s-c.me/, ваши цвета приятней, но вот то что namespace подсвечивается как тег несколько неинтересно, либо бы по особому подсвечивался, либо пусть как в s-c.me будет общим с элементом, а то получается странно ;)
                  0
                  Я над Geshi не властен :) Может быть, будет отдельная подстветка для XSL. Впрочем, можно будет написать, наверное, языковой файл самостоятельно.
                    0
                    ну geshi'вскоя подсветка xml меня вполне устраивает.(разве что цвета сделать более жизнерадостными) Юзаю ее в вики. Все норм. Хотя файл для xsl был бы нелишним, но это некритично :)
              0
              Кстати, если кто захочет сделать саму страничку более приличной, с удовольствием приму форматирующий CSS или переделанный HTML. Обязуюсь оставить копирайт на дизайн :)
                0
                Есть еще вот такая подсвечивалка http://quickhighlighter.com с очень большим количеством языков и настройками. Посмотри может пригодится для усовершенствования твоей.

                А вообще порыв замечательный — зачем пользоваться сторонним «если мы и сам с усам».
                  0
                  да, Geshi это круто, сам юзаю. Только вот рантайм её жрёт много для больших объемов…

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

                Самое читаемое