srchub-old

srchub-old Mercurial Source Tree


Root/indefero/src/IDF/FileUtil.php

<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008-2011 CĂ©ondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
# ***** END LICENSE BLOCK ***** */

/**
 * File utilities.
 *
 */
class IDF_FileUtil
{
    /**
     * Extension supported by the syntax highlighter.
     */
    public static $supportedExtenstions = array(
              'ascx', 'ashx', 'asmx', 'aspx', 'browser', 'bsh', 'c', 'cl', 'cc',
              'config', 'cpp', 'cs', 'csh', 'csproj', 'css', 'cv', 'cyc', 'el', 'fs',
              'h', 'hh', 'hpp', 'hs', 'html', 'html', 'java', 'js', 'lisp', 'master',
              'pas', 'perl', 'php', 'pl', 'pm', 'py', 'rb', 'scm', 'sh', 'sitemap',
              'skin', 'sln', 'svc', 'vala', 'vb', 'vbproj', 'vbs', 'wsdl', 'xhtml',
              'xml', 'xsd', 'xsl', 'xslt');

    public static $map = array("cxx" => "cpp", "h" => "cpp", "hpp" => "cpp", "rc"=>"text", "sh"=>"bash", "cs"=>"csharp");

    public static $syntaxhighlightext = array("html", "as3", "cf", "cpp", "c", "css", "pas", "diff", "patch", "erl", "java", "jfx", "js", "pl", "php", "py", "rb", "sass", "scss", "scala", "sql", "vb", );


    /**
     * Test if an extension is supported by the syntax highlighter.
     *
     * @param string The extension to test
     * @return bool
     */
    public static function isSupportedExtension($extension)
    {
        return in_array($extension, self::$supportedExtenstions);
    }

    /**
     * Returns a HTML snippet with a line-by-line pre-rendered table
     * for the given source content
     *
     * @param array file information as returned by getMimeType or getMimeTypeFromContent
     * @param string the content of the file
     * @return string
     */
    public static function highLight($fileinfo, $content)
    {

        $pretty = '';
        if (self::isSupportedExtension($fileinfo[2])) {
            $pretty = ' prettyprint';
        }
        $table = array();
        $i = 1;
        /*foreach (self::splitIntoLines($content) as $line) {
            $table[] = '<tr class="c-line"><td class="code-lc" id="L'.$i.'"><a href="#L'.$i.'">'.$i.'</a></td>'
                .'<td class="code mono'.$pretty.'">'.self::emphasizeControlCharacters(Pluf_esc($line)).'</td></tr>';
            $i++;
        }
        return Pluf_Template::markSafe(implode("\n", $table));*/
        //var_dump($fileinfo);
        $ext = "";
        if (in_array($fileinfo[2], self::$syntaxhighlightext))
            $ext = $fileinfo[2];
        elseif (array_key_exists($fileinfo[2], self::$map))
            $ext = self::$map[$fileinfo[2]];
        else
            $ext = "text";
        if ($ext == "php" || $ext == "html" || $ext == "htm" || $ext == "js")
            $content = '<div id="highlight"><pre class="brush: ' . $ext . '">' . str_replace("<", "<", $content)  . '</pre></div>';
        else
            $content = '<div id="highlight"><script type="syntaxhighlighter" class="brush: ' . $ext . '">' . $content . '</script></div>';
        return  Pluf_Template::markSafe($content);
    }

    /**
     * Find the mime type of a file.
     *
     * Use /etc/mime.types to find the type.
     *
     * @param string Filename/Filepath
     * @param array  Mime type found or 'application/octet-stream', basename, extension
     */
    public static function getMimeType($file)
    {
        static $mimes = null;
        if ($mimes == null) {
            $mimes = array();
            $src = Pluf::f('idf_mimetypes_db', '/etc/mime.types');
            $filecontent = @file_get_contents($src);
            if ($filecontent !== false) {
                $mimes = preg_split("/\015\012|\015|\012/", $filecontent);
            }
        }

        $info = pathinfo($file);
        if (isset($info['extension'])) {
            foreach ($mimes as $mime) {
                if ('#' != substr($mime, 0, 1)) {
                    $elts = preg_split('/ |\t/', $mime, -1, PREG_SPLIT_NO_EMPTY);
                    if (in_array($info['extension'], $elts)) {
                        return array($elts[0], $info['basename'], $info['extension']);
                    }
                }
            }
        } else {
            // we consider that if no extension and base name is all
            // uppercase, then we have a text file.
            if ($info['basename'] == strtoupper($info['basename'])) {
                return array('text/plain', $info['basename'], 'txt');
            }
            $info['extension'] = 'bin';
        }
        return array('application/octet-stream', $info['basename'], $info['extension']);
    }

    /**
     * Find the mime type of a file using the fileinfo class.
     *
     * @param string Filename/Filepath
     * @param string File content
     * @return array Mime type found or 'application/octet-stream', basename, extension
     */
    public static function getMimeTypeFromContent($file, $filedata)
    {
        $info = pathinfo($file);
        $res = array('application/octet-stream',
                     $info['basename'],
                     isset($info['extension']) ? $info['extension'] : 'bin');
        if (function_exists('finfo_open')) {
            $finfo = finfo_open(FILEINFO_MIME);
            $mime = finfo_buffer($finfo, $filedata);
            finfo_close($finfo);
            if ($mime) {
                $res[0] = $mime;
            }
            if (!isset($info['extension']) && $mime) {
                $res[2] = (0 === strpos($mime, 'text/')) ? 'txt' : 'bin';
            } elseif (!isset($info['extension'])) {
                $res[2] = 'bin';
            }
        }
        return $res;
    }

    /**
     * Splits a string into separate lines while retaining the individual
     * line ending character for every line.
     *
     * OS 9 line endings are not supported.
     *
     * @param string content
     * @param boolean if true, skip completely empty lines
     * @return string
     */
    public static function splitIntoLines($content, $skipEmpty = false)
    {
        $last_off = 0;
        $lines = array();
        while (preg_match("/\r\n|\n/", $content, $m, PREG_OFFSET_CAPTURE, $last_off)) {
            $next_off = strlen($m[0][0]) + $m[0][1];
            $line = substr($content, $last_off, $next_off - $last_off);
            $last_off = $next_off;
            if ($line !== $m[0][0] || !$skipEmpty) $lines[] = $line;
        }
        $line = substr($content, $last_off);
        if ($line !== false && strlen($line) > 0) $lines[] = $line;
        return $lines;
    }

    /**
     * This translates most of the C0 ASCII control characters into
     * their visual counterparts in the 0x24## unicode plane
     * (http://en.wikipedia.org/wiki/C0_and_C1_control_codes).
     *
     * We could add DEL (0x7F) to this set, but unfortunately this
     * is not nicely mapped to 0x247F in the control plane, but 0x2421
     * and adding an if expression below just for this is a little bit
     * of a hassle. And of course, the more esoteric ones from C1 are
     * missing as well...
     *
     * @param string $content
     * @return string
     */
    public static function emphasizeControlCharacters($content)
    {
        return preg_replace(
            '/([\x00-\x1F])/ue',
            '"<span class=\"ctrl-char\" title=\"0x".bin2hex("\\1")."\">$".bin2hex("\\1")."</span>"',
            $content);
    }

    /**
     * Find if a given mime type is a text file.
     * This uses the output of the self::getMimeType function.
     *
     * @param array (Mime type, file name, extension)
     * @return bool Is text
     */
    public static function isText($fileinfo)
    {
        if (0 === strpos($fileinfo[0], 'text/')) {
            return true;
        }
        $ext = 'mdtext php-dist h gitignore diff patch';
        $extra_ext = trim(Pluf::f('idf_extra_text_ext', ''));
        if (!empty($extra_ext))
            $ext .= ' ' . $extra_ext;
        $ext = array_merge(self::$supportedExtenstions, explode(' ' , $ext));
        return (in_array($fileinfo[2], $ext));
    }
}
Source at commit 23012f799d08 created 10 years 18 days ago.
By Nathan Adams, Adding syntax highlighter to base.html

Archive Download this file

Branches

Tags

Page rendered in 0.56682s using 11 queries.