diff options
-rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
-rw-r--r-- | pygments/lexers/php.py | 61 | ||||
-rw-r--r-- | tests/examplefiles/psysh_test.psysh | 47 |
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" |