summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/php.py61
-rw-r--r--tests/examplefiles/psysh_test.psysh47
3 files changed, 105 insertions, 4 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index b98f3de4..8e38a902 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -352,6 +352,7 @@ LEXERS = {
'PromQLLexer': ('pygments.lexers.promql', 'PromQL', ('promql',), ('*.promql',), ()),
'PropertiesLexer': ('pygments.lexers.configs', 'Properties', ('properties', 'jproperties'), ('*.properties',), ('text/x-java-properties',)),
'ProtoBufLexer': ('pygments.lexers.dsls', 'Protocol Buffer', ('protobuf', 'proto'), ('*.proto',), ()),
+ 'PsyshConsoleLexer': ('pygments.lexers.php', 'PsySH console session for PHP', ('psysh',), (), ()),
'PugLexer': ('pygments.lexers.html', 'Pug', ('pug', 'jade'), ('*.pug', '*.jade'), ('text/x-pug', 'text/x-jade')),
'PuppetLexer': ('pygments.lexers.dsls', 'Puppet', ('puppet',), ('*.pp',), ()),
'PyPyLogLexer': ('pygments.lexers.console', 'PyPy Log', ('pypylog', 'pypy'), ('*.pypylog',), ('application/x-pypylog',)),
diff --git a/pygments/lexers/php.py b/pygments/lexers/php.py
index f9ce1d4b..1dd3c52b 100644
--- a/pygments/lexers/php.py
+++ b/pygments/lexers/php.py
@@ -11,13 +11,15 @@
import re
-from pygments.lexer import RegexLexer, include, bygroups, default, using, \
- this, words
+from pygments.lexer import Lexer, RegexLexer, include, bygroups, default, \
+ using, this, words, do_insertions
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
- Number, Punctuation, Other
+ Number, Punctuation, Other, Generic
from pygments.util import get_bool_opt, get_list_opt, shebang_matches
-__all__ = ['ZephirLexer', 'PhpLexer']
+__all__ = ['ZephirLexer', 'PsyshConsoleLexer', 'PhpLexer']
+
+line_re = re.compile('.*?\n')
class ZephirLexer(RegexLexer):
@@ -85,6 +87,57 @@ class ZephirLexer(RegexLexer):
}
+class PsyshConsoleLexer(Lexer):
+ """
+ For `PsySH`_ console output, such as:
+
+ .. sourcecode:: psysh
+
+ >>> $greeting = function($name): string {
+ ... return "Hello, {$name}";
+ ... };
+ => Closure($name): string {#2371 …3}
+ >>> $greeting('World')
+ => "Hello, World"
+
+ .. _PsySH: https://psysh.org/
+ .. versionadded:: 2.7
+ """
+ name = 'PsySH console session for PHP'
+ aliases = ['psysh']
+
+ def __init__(self, **options):
+ options['startinline'] = True
+ Lexer.__init__(self, **options)
+
+ def get_tokens_unprocessed(self, text):
+ phplexer = PhpLexer(**self.options)
+ curcode = ''
+ insertions = []
+ for match in line_re.finditer(text):
+ line = match.group()
+ if line.startswith(u'>>> ') or line.startswith(u'... '):
+ insertions.append((len(curcode),
+ [(0, Generic.Prompt, line[:4])]))
+ curcode += line[4:]
+ elif line.rstrip() == u'...':
+ insertions.append((len(curcode),
+ [(0, Generic.Prompt, u'...')]))
+ curcode += line[3:]
+ else:
+ if curcode:
+ for item in do_insertions(
+ insertions, phplexer.get_tokens_unprocessed(curcode)):
+ yield item
+ curcode = ''
+ insertions = []
+ yield match.start(), Generic.Output, line
+ if curcode:
+ for item in do_insertions(insertions,
+ phplexer.get_tokens_unprocessed(curcode)):
+ yield item
+
+
class PhpLexer(RegexLexer):
"""
For `PHP <http://www.php.net/>`_ source code.
diff --git a/tests/examplefiles/psysh_test.psysh b/tests/examplefiles/psysh_test.psysh
new file mode 100644
index 00000000..4ab9b134
--- /dev/null
+++ b/tests/examplefiles/psysh_test.psysh
@@ -0,0 +1,47 @@
+>>> (int) 10.88
+=> 10
+>>> (string) 10.88
+=> "10.88"
+>>> (bool) 10.88
+=> true
+>>> (array) 10.88
+=> [
+ 10.88,
+ ]
+>>> $object = (object) 10.88
+=> {#2373
+ +"scalar": 10.88,
+ }
+>>> $object->scalar
+=> 10.88
+>>> $fileHandle = fopen('hello.txt', 'w');
+=> stream resource #400
+>>> (int) $fileHandle
+=> 400
+>>> (string) $fileHandle
+=> "Resource id #400"
+>>> $greeting = 'Hello!';
+=> "Hello!"
+>>> $_greeting = 'Hello!';
+=> "Hello!"
+>>> $gruß = 'Hallo!';
+=> "Hallo!"
+>>> namespace Foo\Bar;
+>>> class Baz {
+... public function getBaz(): string {
+... return 'baz';
+... }
+... }
+>>> $baz = new Foo\Bar\Baz();
+PHP Fatal error: Class 'Foo/Bar/Foo/Bar/Baz' not
+ found in Psy Shell code on line 1
+>>> $baz = new Baz();
+=> Foo\Bar\Baz {#2382}
+>>> $baz->getBaz();
+=> "baz"
+>>> $greeting = function($name): string {
+... return "Hello, {$name}";
+... };
+=> Closure($name): string {#2371 …3}
+>>> $greeting('World')
+=> "Hello, World"