r38875 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r38874‎ | r38875 | r38876 >
Date:10:23, 8 August 2008
Author:tstarling
Status:old
Tags:
Comment:
A PHP code beautifier aimed at adding lots of spaces to files that lack them, in keeping with MediaWiki's spacey site style.
Modified paths:
  • /trunk/tools/stylize.php (added) (history)

Diff [purge]

Index: trunk/tools/stylize.php
@@ -0,0 +1,279 @@
 2+<?php
 3+
 4+/**
 5+ * A PHP code beautifier aimed at adding lots of spaces to files that lack them,
 6+ * in keeping with MediaWiki's spacey site style.
 7+ */
 8+
 9+
 10+if ( php_sapi_name() != 'cli' ) {
 11+ print "This script must be run from the command line\n";
 12+ exit( 1 );
 13+}
 14+array_shift( $argv );
 15+if ( count( $argv ) ) {
 16+ foreach ( $argv as $filename ) {
 17+ stylize_file( $filename );
 18+ }
 19+} else {
 20+ stylize_file( '-' );
 21+}
 22+
 23+function stylize_file( $filename ) {
 24+ if ( $filename == '-' ) {
 25+ $s = file_get_contents( '/dev/stdin' );
 26+ if ( $s === false ) {
 27+ return;
 28+ }
 29+ $stylizer = new Stylizer( $s );
 30+ $s = $stylizer->stylize();
 31+ echo $s;
 32+ } else {
 33+ $s = file_get_contents( $filename );
 34+ if ( $s === false ) {
 35+ return;
 36+ }
 37+ $stylizer = new Stylizer( $s );
 38+ $s = $stylizer->stylize();
 39+ rename( $filename, "$filename~" );
 40+ file_put_contents( $filename, $s );
 41+ }
 42+}
 43+
 44+class Stylizer {
 45+ var $tokens, $p;
 46+
 47+ static $tablesInitialised = false;
 48+ static $xSpaceBefore, $xSpaceAfter;
 49+
 50+ static $space = array(
 51+ T_WHITESPACE,
 52+ 'START',
 53+ 'END',
 54+ );
 55+ static $spaceBothSides = array(
 56+ T_AND_EQUAL,
 57+ T_AS,
 58+ T_BOOLEAN_AND,
 59+ T_BOOLEAN_OR,
 60+ T_CASE,
 61+ T_CATCH,
 62+ T_CLONE,
 63+ T_CONCAT_EQUAL,
 64+ T_DIV_EQUAL,
 65+ T_DO,
 66+ T_DOUBLE_ARROW,
 67+ T_ELSE,
 68+ T_ELSEIF,
 69+ T_FOR,
 70+ T_FOREACH,
 71+ T_IF,
 72+ T_IS_EQUAL,
 73+ T_IS_GREATER_OR_EQUAL,
 74+ T_IS_IDENTICAL,
 75+ T_IS_NOT_EQUAL,
 76+ T_IS_NOT_IDENTICAL,
 77+ T_IS_SMALLER_OR_EQUAL,
 78+ T_LOGICAL_AND,
 79+ T_LOGICAL_OR,
 80+ T_LOGICAL_XOR,
 81+ T_MOD_EQUAL,
 82+ T_MUL_EQUAL,
 83+ T_OR_EQUAL,
 84+ T_PLUS_EQUAL,
 85+ T_SL,
 86+ T_SL_EQUAL,
 87+ T_SR,
 88+ T_SR_EQUAL,
 89+ T_TRY,
 90+ T_WHILE,
 91+ T_XOR_EQUAL,
 92+ '{',
 93+ '}',
 94+ '%',
 95+ '^',
 96+ // '&', can be unary, we have a special case for =&
 97+ '*',
 98+ '-',
 99+ '=',
 100+ '+',
 101+ '|',
 102+ //':', can be a case label
 103+ '.',
 104+ '<',
 105+ '>',
 106+ '/',
 107+ '?',
 108+ );
 109+ static $spaceBefore = array(
 110+ ')'
 111+ );
 112+ static $spaceAfter = array(
 113+ '(',
 114+ ';',
 115+ ',',
 116+ );
 117+ static $closePairs = array(
 118+ '(' => ')',
 119+ '=' => '&',
 120+ );
 121+
 122+ // Tokens that eat spaces after them
 123+ static $spaceEaters = array(
 124+ T_COMMENT,
 125+ T_OPEN_TAG,
 126+ T_OPEN_TAG_WITH_ECHO,
 127+ );
 128+
 129+ var $endl = "
 130+";
 131+
 132+
 133+ function __construct( $s ) {
 134+ $s = str_replace( "\r\n", "\n", $s );
 135+ $this->tokens = token_get_all( $s );
 136+ if ( !self::$tablesInitialised ) {
 137+ self::$xSpaceBefore = array_combine(
 138+ array_merge( self::$spaceBefore, self::$spaceBothSides ),
 139+ array_fill( 0, count( self::$spaceBefore ) + count( self::$spaceBothSides ), true )
 140+ );
 141+ self::$xSpaceAfter = array_combine(
 142+ array_merge( self::$spaceAfter, self::$spaceBothSides ),
 143+ array_fill( 0, count( self::$spaceAfter ) + count( self::$spaceBothSides ), true )
 144+ );
 145+ }
 146+ }
 147+
 148+ function get( $i ) {
 149+ if ( $i < 0 ) {
 150+ return array( 'START', '' );
 151+ } elseif( $i >= count( $this->tokens ) ) {
 152+ return array( 'END', '' );
 153+ } else {
 154+ $token = $this->tokens[$i];
 155+ if ( is_string( $token ) ) {
 156+ return array( $token, $token );
 157+ } else {
 158+ return array( $token[0], $token[1] );
 159+ }
 160+ }
 161+ }
 162+
 163+ function getCurrent() {
 164+ return $this->get( $this->p );
 165+ }
 166+
 167+ function getPrev() {
 168+ return $this->get( $this->p - 1 );
 169+ }
 170+
 171+ function getNext() {
 172+ return $this->get( $this->p + 1 );
 173+ }
 174+
 175+ function isSpace( $token ) {
 176+ if ( in_array( $token[0], self::$space ) ) {
 177+ return true;
 178+ }
 179+ // Some other tokens can eat whitespace
 180+ if ( in_array( $token[0], self::$spaceEaters ) && preg_match( '/\s$/', $token[1] ) ) {
 181+ return true;
 182+ }
 183+ return false;
 184+ }
 185+
 186+ function isSpaceBefore( $token ) {
 187+ return isset( self::$xSpaceBefore[$token[0]] );
 188+ }
 189+
 190+ function isSpaceAfter( $token ) {
 191+ return isset( self::$xSpaceAfter[$token[0]] );
 192+ }
 193+
 194+ function consumeUpTo( $endType ) {
 195+ $token = $this->getCurrent();
 196+ $out = $token[1];
 197+ do {
 198+ $this->p++;
 199+ $token = $this->getCurrent();
 200+ $out .= $token[1];
 201+ } while ( $this->p < count( $this->tokens ) && $token[0] != $endType );
 202+ return $out;
 203+ }
 204+
 205+ function stylize() {
 206+ $out = '';
 207+ for ( $this->p = 0; $this->p < count( $this->tokens ); $this->p++ ) {
 208+ list( $prevType, $prevText ) = $prevToken = $this->getPrev();
 209+ list( $curType, $curText ) = $curToken = $this->getCurrent();
 210+ list( $nextType, $nextText ) = $nextToken = $this->getNext();
 211+
 212+ // Don't format strings
 213+ if ( $curType == '"' ) {
 214+ $out .= $this->consumeUpTo( '"' );
 215+ continue;
 216+ } elseif ( $curType == T_START_HEREDOC ) {
 217+ $out .= $this->consumeUpTo( T_END_HEREDOC );
 218+ continue;
 219+ } elseif ( $curType == "'" ) {
 220+ // For completeness
 221+ $out .= $this->consumeUpTo( "'" );
 222+ continue;
 223+ }
 224+
 225+ // Detect close pairs like ()
 226+ $closePairBefore = isset( self::$closePairs[$prevType] )
 227+ && $curType == self::$closePairs[$prevType];
 228+ $closePairAfter = isset( self::$closePairs[$curType] )
 229+ && $nextType == self::$closePairs[$curType];
 230+
 231+ // Add space before
 232+ if ( $this->isSpaceBefore( $curToken )
 233+ && !$this->isSpace( $prevToken )
 234+ && !$closePairBefore
 235+ ) {
 236+ $out .= ' ';
 237+ }
 238+
 239+ // Add the token contents
 240+ if ( $curType == T_COMMENT ) {
 241+ $curText = $this->fixComment( $curText );
 242+ } elseif ( $curType == T_WHITESPACE ) {
 243+ $curText = $this->fixWhitespace( $curText );
 244+ }
 245+
 246+ $out .= $curText;
 247+
 248+ $wantSpaceAfter = $this->isSpaceAfter( $curToken );
 249+ // Special case: space after =&
 250+ if ( $prevType == '=' && $curType == '&' ) {
 251+ $wantSpaceAfter = true;
 252+ }
 253+
 254+ // Add space after
 255+ if ( $wantSpaceAfter
 256+ && !$closePairAfter
 257+ && !$this->isSpace( $nextToken )
 258+ && !$this->isSpaceBefore( $nextToken )
 259+ ) {
 260+ $out .= ' ';
 261+ }
 262+ }
 263+ $out = str_replace( "\n", $this->endl, $out );
 264+ return $out;
 265+ }
 266+
 267+ function fixComment( $s ) {
 268+ // Fix single-line comments with no leading whitespace
 269+ if ( preg_match( '!^(#|//)(\S.*)$!s', $s, $m ) ) {
 270+ $s = $m[1] . ' ' . $m[2];
 271+ }
 272+ return $s;
 273+ }
 274+
 275+ function fixWhitespace( $s ) {
 276+ // Fix whitespace at the line end
 277+ return preg_replace( '!^([\t ]+)(\n.*)$!s', '\2', $s, 1 );
 278+ }
 279+
 280+}
Property changes on: trunk/tools/stylize.php
___________________________________________________________________
Added: svn:eol-style
1281 + native

Status & tagging log