Hello,

for the purpose of automatically building a syntax highlighting file for
jEdit I wanted to write a script that does this automatically by
retrieving http://php.net/quickref.php and extracting it.

Unfortunately the syntax for the function names there is not trivial.

For example, the swfbitmap::getheight() is named (content of the <a>
tag) swfbitmap.getheight in the list. This is great and could be easily
detected (because of the point).

But AFAICS the SWF classes are the only ones that use this naming
convention.

So I've taken the output from PHP 5.0.3's get_declared_classes() and
test if the part of the function name before the first '_' is one of
those classes and handle it as a class function then (cut the class name
in front).

Another problem are the old DOM-XML class functions that are prefixed with
'dom_', which I optionally match in the regexp.

Wouldn't it be easier to use the syntax "class.function_name" for the
names?

I've attached the script, so you can probably better understand what I
mean.. ;)


-- 
happy new year!
<?php
/**
 * This script gets the PHP function list from php.net, the alias list from
 * zend.org and builds keyword blocks for jEdit's php.xml mode file.
 *
 * @author daniel hahler (http://thequod.de/contact)
 * @version 2004-12-30
 */

error_reporting(E_ALL);

$urls = array(
                                        'quickref' => 
'http://www.php.net/quickref.php',
                                        'aliases' => 
'http://zend.com/phpfunc/all_aliases.php',
                                );


/**
 * @var array holds all functions
 */
$functions = array();
/**
 * @var array holds all functions for classes (classnames are keys)
 */
$functionsForClasses = array( // {{{
        'arrayiterator' => array(),
        'arrayobject' => array(),
        'cachingiterator' => array(),
        'cachingrecursiveiterator' => array(),
        'com' => array(),
        'compersisthelper' => array(),
        'com_exception' => array(),
        'com_safearray_proxy' => array(),
        'directory' => array(),
        'directoryiterator' => array(),
        'domattr' => array(),
        'domcdatasection' => array(),
        'domcharacterdata' => array(),
        'domcomment' => array(),
        'domconfiguration' => array(),
        'domdocument' => array(),
        'domdocumentfragment' => array(),
        'domdocumenttype' => array(),
        'domdomerror' => array(),
        'domelement' => array(),
        'domentity' => array(),
        'domentityreference' => array(),
        'domerrorhandler' => array(),
        'domexception' => array(),
        'domimplementation' => array(),
        'domimplementationlist' => array(),
        'domimplementationsource' => array(),
        'domlocator' => array(),
        'domnamednodemap' => array(),
        'domnamelist' => array(),
        'domnamespacenode' => array(),
        'domnode' => array(),
        'domnodelist' => array(),
        'domnotation' => array(),
        'domprocessinginstruction' => array(),
        'domstringextend' => array(),
        'domstringlist' => array(),
        'domtext' => array(),
        'domtypeinfo' => array(),
        'domuserdatahandler' => array(),
        'domxpath' => array(),
        'dotnet' => array(),
        'exception' => array(),
        'filteriterator' => array(),
        'limititerator' => array(),
        'parentiterator' => array(),
        'php_user_filter' => array(),
        'recursivedirectoryiterator' => array(),
        'recursiveiteratoriterator' => array(),
        'reflection' => array(),
        'reflectionclass' => array(),
        'reflectionexception' => array(),
        'reflectionextension' => array(),
        'reflectionfunction' => array(),
        'reflectionmethod' => array(),
        'reflectionobject' => array(),
        'reflectionparameter' => array(),
        'reflectionproperty' => array(),
        'simplexmlelement' => array(),
        'simplexmliterator' => array(),
        'sqlitedatabase' => array(),
        'sqliteexception' => array(),
        'sqliteresult' => array(),
        'sqliteunbuffered' => array(),
        'variant' => array(),
        
        // autodetect-classes ("class.function" syntax) without methods (to get 
removed)
        'swfaction' => array(),
        
        /**
         * @obsolete PHP4
         */
        'domattribute' => array(),
        'domxsltstylesheet' => array(),
); // }}}


// Get PHP's quickref-list and extract it {{{
$buffer = file_get_contents( $urls['quickref'] );

preg_match_all( '#<a href="/manual/en/function\.[^>]+>(?:(\w+)\.)?(\w+)</a>#', 
$buffer, $matches, PREG_PATTERN_ORDER );

foreach( $matches[2] as $lKey => $lFunction )
{
        if( !empty( $matches[1][$lKey] ) )
        { // this is a class function ("class.function")
                $functionsForClasses[$matches[1][$lKey]][] = $lFunction;
        }
        elseif( preg_match( '#^(?:dom_)?([a-z]+)_(.*)$#', $lFunction, $match )
                                        && isset( 
$functionsForClasses[$match[1]] ) )
        { // this is also a class function, not divided with a dot
                $functionsForClasses[$match[1]][] = $match[2];
        }
        else
        {
                addFunction( $lFunction );
        }
}
// }}}


// Remove constructors from function list (those that have been discovered
// through class.function syntax
foreach( array_keys($functions) as $lFunction )
{
        if( isset( $functionsForClasses[$lFunction] ) )
        {
                unset( $functions[$lFunction] );
        }
}


// Get Zend's Alias list and extract it {{{
$buffer = file_get_contents( $urls['aliases'] );

preg_match_all( '#<tr[^>]*>'
                                                                .'<td[^>]*><a 
href="[^"]*function.\w+.php">(\w+)</a></td>' // alias
                                                                .'<td><a 
[^>]+>[^<]+</a></td>' // source
                                                                .'<td><a 
href="function.*?">\w+</a></td></tr>#', // orig
                                                                $buffer, 
$matches, PREG_PATTERN_ORDER );

$aliases = isset( $matches[1] ) ?
                                                array_unique($matches[1]) :
                                                array();
natsort( $aliases );
// }}}


/**
 * Internal function to echo a keyword
 */
function echo_keyword( $keyword, $nr = '2', $srcArray = NULL )
{
        echo "\t\t\t<KEYWORD$nr>$keyword</KEYWORD$nr>";
        
        if( is_array( $srcArray ) && isset($srcArray[0]) )
        {
                echo ' <!-- '.implode( ', ', $srcArray ).' -->';
        }
        
        echo "\n";
}


function addFunction( $name, $src = NULL )
{
        global $functions;
        
        $_src = isset( $functions[$name] ) ?
                                                $functions[$name]['src'] :
                                                array();

        if( !is_null( $src ) )
        {
                if( !is_array( $src ) )
                {
                        $_src[] = $src;
                }
                else
                {
                        $_src = array_merge( $_src, $src );
                }
        }
        
        $functions[$name]['src'] = $_src;
}


ksort($functionsForClasses);

echo "\t\t\t<!-- Internal classes (".count( $functionsForClasses ).") -->\n";
foreach( $functionsForClasses as $lClass => $lFunctions )
{
        echo_keyword( $lClass );

        // add the class functions to the global list
        foreach( $lFunctions as $lFunction )
        {
                addFunction( $lFunction, $lClass );
        }
}


uksort( $functions, 'strnatcasecmp' );

echo "\n\t\t\t<!-- Internal functions (".count( $functions ).") -->\n";
foreach( $functions as $lFunction => $lValue )
{
        echo_keyword( $lFunction, '2', $lValue['src'] );
}


if( $count = count( $aliases ) )
{ // Output aliases
        echo "\n\t\t\t<!-- Alias functions (".count( $aliases ).") -->\n";
        foreach( $aliases as $lAlias )
        {
                echo_keyword( $lAlias, '4' );
        }
}

?>
-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to