Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Made improvements to pretty printing #116

Closed
wants to merge 3 commits into from
Closed

Made improvements to pretty printing #116

wants to merge 3 commits into from

Conversation

BluntSporks
Copy link

Hi, I found this PHP-Parser project and it appears quite useful. I started using the PHP Pretty Printer, and wrote a number of changes to this feature that I think are improvements. They are in this changeset that I am making available to you in case you want to pull the changes (or any part of them that you find useful).

Summary of the changes:

  1. Wrote a fixTokens() function to fix the PHP Tokens so that any space found attached to a PHP end tag, ?>, is instead moved to the HTML following the end tag so it is preserved.
  2. Saved information about heredoc and nowdoc tags in the parser so that the actual heredoc and nowdoc tags can be preserved on request.
  3. Added a name callback function to transform constant names, for example, all instances of TRUE, FALSE, and NULL can be transformed to true, false, and null by using strtolower() as the callback.
  4. Allowing strings that end in newlines to encode the newline because it looks better, for example, "\n" or "This is an example\n" will keep the \n sequence.
  5. Rewrote the array printing function so that the arrays are nicely wrapped and easier to read.
  6. Rewrote how the open brace and close brace are handled, so that the formatting of open brace and close brace can be changed systematically just by setting some configuration parameters. This is useful when following different coding styles that mandate different types of indentation and brace syntax.
  7. Allowed blank lines before comments if a configuration parameter is set.
  8. Changed the prettyPrintFile() to optionally include the closing tag if that is requested, since some standards require that.
  9. Wrote a wrapLines() function that takes prettified code and wraps it after specified token types to within a given line length, since most formatting standards require that. I thought a separate function was easier to understand than modifying all of the existing functions.

I can give you some examples of before and after code and show you how much this is improved in terms of flexibility and appearance of output.

The rest of this message consists of a pretty printer script that I wrote which uses most of these new features.

#!/usr/bin/php
<?php

/**
 * This is a pretty-printer using PHP Parser
 */
if ($argc != 2) {
   die("Usage: {$argv['0']} [filename]\n");
}
$fileName = $argv[1];
if (!file_exists($fileName)) {
   die("File {$fileName} not found\n");
}
require '/home/dsg/library/PHP-Parser/lib/bootstrap.php';
ini_set('xdebug.max_nesting_level', 2000);
$sourceCode = file_get_contents($fileName);
$parser = new PhpParser\Parser(new PhpParser\Lexer());
$prettyPrinter = new PhpParser\PrettyPrinter\Standard();

// Configure general formatting
$prettyPrinter->setIndentString('   ');
$prettyPrinter->setUseBlankBeforeComment(true);
$prettyPrinter->setUseArrayIndent(true);
$prettyPrinter->setPreserveHeredoc(true);
$prettyPrinter->setNameCallback('strtolower');

// Configure string length and line wrap
$prettyPrinter->setLineWrap(120);
$prettyPrinter->addWrapToken(',');
$prettyPrinter->addWrapToken('.');
$prettyPrinter->addWrapToken(T_BOOLEAN_AND);
$prettyPrinter->addWrapToken(T_BOOLEAN_OR);
$prettyPrinter->addWrapToken(T_LOGICAL_AND);
$prettyPrinter->addWrapToken(T_LOGICAL_OR);
$prettyPrinter->addWrapToken(T_LOGICAL_XOR);

// Configure line breaks before keywords
$prettyPrinter->setKeywordNewline('catch');
$prettyPrinter->setKeywordNewline('else');
$prettyPrinter->setKeywordNewline('elseif');
$prettyPrinter->setKeywordNewline('finally');
$prettyPrinter->setKeywordNewline('while');
try {

   // Parse
   $stmts = $parser->parse($sourceCode);

   // Pretty print
   $prettyCode = $prettyPrinter->prettyPrintFile($stmts, true);
   $wrappedCode = $prettyPrinter->wrapLines($prettyCode);
   file_put_contents($fileName, $wrappedCode);
   echo "Wrote {$fileName}\n";
}
catch (PhpParser\Error $e) {
   echo "Error parsing {$fileName}: ", $e->getMessage();
}
?>

@nikic
Copy link
Owner

nikic commented Jul 29, 2014

Just as a heads up, I think the patch contains many useful changes which should be included, but I currently don't have time to review it and modify it to be generic (e.g. currently it relies on things like IDs of reduction actions, which is something that changes every time the grammar is modified).

@BluntSporks
Copy link
Author

OK, I reviewed this and the only feature that depended on the IDs of reduction actions was the preservation of heredoc strings. That feature is useful to me, so I kept it in my local copy, however I removed it from the version that I posted here in my latest commit. So this change should be ready to review and merge by you. Please let me know if you have any further trouble. Thanks!

@ondrejmirtes
Copy link
Contributor

Look at Travis, you should fix the tests.

@GrahamCampbell
Copy link
Contributor

It would probably be a good idea to rebase against the master too.

@GrahamCampbell
Copy link
Contributor

Any news on this?

@@ -11,7 +11,7 @@ namespace PhpParser;
/* This is an automatically GENERATED file, which should not be manually edited.
* Instead edit one of the following:
* * the grammar file grammar/zend_language_parser.phpy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove the y from phpy if you commit again

@ovr
Copy link
Contributor

ovr commented Sep 10, 2015

Any news on this?

@BluntSporks
Copy link
Author

I thought they weren't interested in the updates and already deleted my
repo. So don't worry about it.

On Thu, Sep 10, 2015 at 6:42 AM, Dmitry Patsura [email protected]
wrote:

Any news on this?


Reply to this email directly or view it on GitHub
#116 (comment).

@joelwurtz
Copy link

For me this should not be the role of this library to pretty print something as this will imply at lot of complexity here.

I have resolved this by piping the generated code through https://github.com/FriendsOfPHP/PHP-CS-Fixer and it works well.

@TomasVotruba
Copy link
Contributor

@joelwurtz That's the same conclusion I came in. Do you still use it?

Now you can use FormatPerservingPrinter: #41 (comment)

I use it and it works well apart few glitches: #400

@m1guelpf
Copy link
Contributor

@nikic I believe this can be closed now...

@nikic
Copy link
Owner

nikic commented Oct 18, 2017

Right, realistically this is not landing at this point. My current stance on the issue is that for non-trivial adjustment to the formatting an existing formatting library should be used, as mentioned in #116 (comment).

@nikic nikic closed this Oct 18, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants