From de706b5ad7bd7f9ee79b945ed87375e1b7aec970 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 21 May 2024 16:19:09 +0200 Subject: [PATCH 01/17] Fixes for PHP attribute parsing --- src/Templates/highlight.php/php.json | 55 ++++++++++++------ .../blocks/code-blocks/php-attributes.html | 57 +++++++++++++------ .../blocks/code-blocks/php-attributes.rst | 11 ++++ 3 files changed, 87 insertions(+), 36 deletions(-) diff --git a/src/Templates/highlight.php/php.json b/src/Templates/highlight.php/php.json index 3f127b8..7295ab9 100644 --- a/src/Templates/highlight.php/php.json +++ b/src/Templates/highlight.php/php.json @@ -11,17 +11,30 @@ "keywords": "and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try match switch continue endfor endif declare unset true false goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally", "contains": [ { - "className": "php-attribute", - "begin": "#\\[\\s*(\\\\?[A-Z][A-Za-z0-9_\\x7f-\\xff]+|\\\\?[A-Z]+(?=[A-Z][a-z0-9_\\x7f-\\xff])){1,}(?![A-Za-z0-9])(?![$])", + "className": "meta", + "begin": "#\\[\\s*(\\\\?[A-Z][A-Za-z0-9_\\x7f-\\xff]+)+\\]" + }, + { + "begin": "#\\[\\s*(\\\\?[A-Z][A-Za-z0-9_\\x7f-\\xff]+)+(?![A-Za-z0-9])(?![$])", "end": "]", + "returnBegin": true, "contains": [ + { + "className": "meta", + "begin": "#\\[\\s*(\\\\?[A-Z][A-Za-z0-9_\\x7f-\\xff]+)+(?![A-Za-z0-9])(?![$])" + }, { "begin": "\\(", "end": "\\)", "keywords": "true false null new array", "contains": { - "$ref": "#contains.10.contains.1.contains" + "$ref": "#contains.11.contains.1.contains" } + }, + { + "className": "meta", + "begin": "]", + "endsParent": true } ] }, @@ -50,7 +63,7 @@ "begin": "<\\?(php)?|\\?>" }, { - "$ref": "#contains.1.contains.0" + "$ref": "#contains.2.contains.0" }, { "className": "doctag", @@ -69,7 +82,7 @@ "begin": "@[A-Za-z]+" }, { - "$ref": "#contains.1.contains.0" + "$ref": "#contains.2.contains.0" }, { "className": "doctag", @@ -84,7 +97,7 @@ "end": false, "contains": [ { - "$ref": "#contains.1.contains.0" + "$ref": "#contains.2.contains.0" }, { "className": "doctag", @@ -120,7 +133,7 @@ ] }, { - "$ref": "#contains.2.contains.0" + "$ref": "#contains.3.contains.0" }, { "className": "variable", @@ -156,7 +169,7 @@ "contains": [ "self", { - "$ref": "#contains.8" + "$ref": "#contains.9" }, { "className": "comment", @@ -164,7 +177,7 @@ "end": "\\*/", "contains": [ { - "$ref": "#contains.1.contains.0" + "$ref": "#contains.2.contains.0" }, { "className": "doctag", @@ -177,10 +190,10 @@ "className": "string", "contains": [ { - "$ref": "#contains.5.contains.0" + "$ref": "#contains.6.contains.0" }, { - "$ref": "#contains.2.contains.0" + "$ref": "#contains.3.contains.0" } ], "variants": [ @@ -199,7 +212,7 @@ "illegal": null, "contains": [ { - "$ref": "#contains.5.contains.0" + "$ref": "#contains.6.contains.0" } ] }, @@ -210,7 +223,7 @@ "illegal": null, "contains": [ { - "$ref": "#contains.5.contains.0" + "$ref": "#contains.6.contains.0" }, { "className": "subst", @@ -239,6 +252,12 @@ "relevance": 0 } ] + }, + { + "$ref": "#contains.0" + }, + { + "$ref": "#contains.1" } ] } @@ -255,7 +274,7 @@ "beginKeywords": "extends implements" }, { - "$ref": "#contains.10.contains.0" + "$ref": "#contains.11.contains.0" } ] }, @@ -265,7 +284,7 @@ "illegal": "[\\.']", "contains": [ { - "$ref": "#contains.10.contains.0" + "$ref": "#contains.11.contains.0" } ] }, @@ -274,7 +293,7 @@ "end": ";", "contains": [ { - "$ref": "#contains.10.contains.0" + "$ref": "#contains.11.contains.0" } ] }, @@ -282,10 +301,10 @@ "begin": "=>" }, { - "$ref": "#contains.10.contains.1.contains.3" + "$ref": "#contains.11.contains.1.contains.3" }, { - "$ref": "#contains.10.contains.1.contains.4" + "$ref": "#contains.11.contains.1.contains.4" } ] } diff --git a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html index 541681c..9ea143e 100644 --- a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html +++ b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html @@ -1,4 +1,4 @@ -
+
1
 2
@@ -53,7 +53,18 @@
 51
 52
 53
-54
+54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65
             
                 // src/SomePath/SomeClass.php
@@ -64,77 +75,87 @@
                     SomeClass
                 
                 {
-                #[AttributeName]
+                #[AttributeName]
                 private
                 
                     $ property1
                 ;
-                #[AttributeName()]
+                #[AttributeName()]
                 private
                 
                     $ property2
                 ;
-                #[AttributeName('value')]
+                #[AttributeName('value')]
                 private
                 
                     $ property3
                 ;
-                #[AttributeName('value', option: 'value')]
+                #[AttributeName('value', option: 'value')]
                 private
                 
                     $ property4
                 ;
-                #[AttributeName(['value' => 'value'])]
+                #[AttributeName(['value' => 'value'])]
                 private
                 
                     $ property5
                 ;
-                #[AttributeName(
+                #[AttributeName(
                     'value',
                     option: 'value'
-                )]
+                )]
                 private
                 
                     $ property6
                 ;
-                #[Assert\AttributeName('value')]
+                #[Assert\AttributeName('value')]
                 private
                 
                     $ property7
                 ;
-                #[Assert\AttributeName(
+                #[Assert\AttributeName(
                     'value',
                     option: 'value'
-                )]
+                )]
                 private
                 
                     $ property8
                 ;
-                #[Route('/blog/{page<\d+>}', name: 'blog_list')]
+                #[Route('/blog/{page<\d+>}', name: 'blog_list')]
                 private
                 
                 $ property9
                 ;
-                #[Assert\GreaterThanOrEqual(
+                #[Assert\GreaterThanOrEqual(
                     value: 18,
-                )]
+                )]
                 private
                 
                 $ property10
                 ;
-                #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
+                #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
                 private
                 
                 $ property11
                 ;
-                #[Assert\AtLeastOneOf([
+                #[Assert\AtLeastOneOf([
                     new Assert\Regex('/#/'),
                     new Assert\Length(min: 10),
-                ])]
+                ])]
                 private
                 
                 $ property12
                 ;
+                public function __construct(
+                        #[TaggedIterator('app.handlers')]
+                        iterable $handlers,
+                ){
+                }
+
+                #[AsController]
+                public functionsomeAction(#[CurrentUser] User $user)
+                {
+                }
 }
diff --git a/tests/fixtures/source/blocks/code-blocks/php-attributes.rst b/tests/fixtures/source/blocks/code-blocks/php-attributes.rst index 31b5f99..808e6c4 100644 --- a/tests/fixtures/source/blocks/code-blocks/php-attributes.rst +++ b/tests/fixtures/source/blocks/code-blocks/php-attributes.rst @@ -53,4 +53,15 @@ new Assert\Length(min: 10), ])] private $property12; + + public function __construct( + #[TaggedIterator('app.handlers')] + iterable $handlers, + ) { + } + + #[AsController] + public function someAction(#[CurrentUser] User $user) + { + } } From 0642507c99fb18751ce7c1143a64ff9948c4e3f1 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 25 May 2024 16:26:23 +0200 Subject: [PATCH 02/17] Add more modern PHP syntax highlighting --- src/Renderers/CodeNodeRenderer.php | 3 - src/Templates/highlight.php/php.json | 155 +++++++++++++++--- tests/IntegrationTest.php | 9 +- tests/Templates/fixtures/php.output.html | 6 +- .../blocks/code-blocks/php-attributes.html | 2 +- .../expected/blocks/code-blocks/php.html | 91 +++++++++- .../expected/blocks/nodes/literal.html | 4 +- tests/fixtures/expected/main/datetime.html | 12 +- .../source/blocks/code-blocks/php.rst | 46 +++++- 9 files changed, 277 insertions(+), 51 deletions(-) diff --git a/src/Renderers/CodeNodeRenderer.php b/src/Renderers/CodeNodeRenderer.php index cfa46a1..a9e5643 100644 --- a/src/Renderers/CodeNodeRenderer.php +++ b/src/Renderers/CodeNodeRenderer.php @@ -70,9 +70,6 @@ public function render(): string $highLighter = new Highlighter(); $highlightedCode = $highLighter->highlight($languageMapping, $code)->value; - - // this allows to highlight the $ in PHP variable names - $highlightedCode = str_replace('$', '$', $highlightedCode); } if ('terminal' === $language) { diff --git a/src/Templates/highlight.php/php.json b/src/Templates/highlight.php/php.json index 7295ab9..c31251a 100644 --- a/src/Templates/highlight.php/php.json +++ b/src/Templates/highlight.php/php.json @@ -8,7 +8,7 @@ "php7" ], "case_insensitive": true, - "keywords": "and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try match switch continue endfor endif declare unset true false goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally", + "keywords": "PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION ZEND_THREAD_SAFE ZEND_DEBUG_BUILD PHP_ZTS PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_OS_FAMILY PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_MIN PHP_INT_SIZE PHP_FLOAT_DIG PHP_FLOAT_EPSILON PHP_FLOAT_MIN PHP_FLOAT_MAX DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_BINARY PHP_MANDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX PHP_FD_SETSIZE E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_RECOVERABLE_ERROR E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT __COMPILER_HALT_OFFSET__ PHP_WINDOWS_EVENT_CTRL_C PHP_WINDOWS_EVENT_CTRL_BREAK PHP_CLI_PROCESS_TITLE STDERR STDIN STDOUT __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once abstract and as binary break case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile enum eval extends final finally for foreach from global goto if implements instanceof insteadof interface isset list match|0 new or parent private protected public readonly return switch throw trait try unset use var void while xor yield array bool boolean callable float int integer iterable mixed never numeric object real string resource self static false FALSE null NULL true TRUE", "contains": [ { "className": "meta", @@ -26,9 +26,10 @@ { "begin": "\\(", "end": "\\)", - "keywords": "true false null new array", + "keywords": "array bool boolean float int integer new real string false FALSE null NULL true TRUE PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION ZEND_THREAD_SAFE ZEND_DEBUG_BUILD PHP_ZTS PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_OS_FAMILY PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_MIN PHP_INT_SIZE PHP_FLOAT_DIG PHP_FLOAT_EPSILON PHP_FLOAT_MIN PHP_FLOAT_MAX DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_BINARY PHP_MANDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX PHP_FD_SETSIZE E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_RECOVERABLE_ERROR E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT __COMPILER_HALT_OFFSET__ PHP_WINDOWS_EVENT_CTRL_C PHP_WINDOWS_EVENT_CTRL_BREAK PHP_CLI_PROCESS_TITLE STDERR STDIN STDOUT __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__", "contains": { - "$ref": "#contains.11.contains.1.contains" + "$ref": "#contains.10.contains.3.contains", + "_": "params" } }, { @@ -137,39 +138,124 @@ }, { "className": "variable", - "begin": "\\$this\\b" - }, - { - "className": "variable", - "begin": "\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*" + "begin": "\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*", + "returnBegin": true, + "contains": [ + { + "className": "variable-other-marker", + "begin": "\\$" + }, + { + "begin": "\\$*[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*" + } + ] }, { - "className": "operator", - "begin": "(::|->)", - "end": "[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*", - "excludeEnd": true + "begin": "\\b(?!fn\\b|function\\b|__CLASS__\\b|__DIR__\\b|__FILE__\\b|__FUNCTION__\\b|__COMPILER_HALT_OFFSET__\\b|__LINE__\\b|__METHOD__\\b|__NAMESPACE__\\b|__TRAIT__\\b|die\\b|echo\\b|exit\\b|include\\b|include_once\\b|print\\b|require\\b|require_once\\b|array\\b|abstract\\b|and\\b|as\\b|binary\\b|bool\\b|boolean\\b|break\\b|callable\\b|case\\b|catch\\b|class\\b|clone\\b|const\\b|continue\\b|declare\\b|default\\b|do\\b|double\\b|else\\b|elseif\\b|empty\\b|enddeclare\\b|endfor\\b|endforeach\\b|endif\\b|endswitch\\b|endwhile\\b|enum\\b|eval\\b|extends\\b|final\\b|finally\\b|float\\b|for\\b|foreach\\b|from\\b|global\\b|goto\\b|if\\b|implements\\b|instanceof\\b|insteadof\\b|int\\b|integer\\b|interface\\b|isset\\b|iterable\\b|list\\b|match\\b|mixed\\b|new\\b|never\\b|object\\b|or\\b|private\\b|protected\\b|public\\b|readonly\\b|real\\b|return\\b|string\\b|switch\\b|throw\\b|trait\\b|try\\b|unset\\b|use\\b|var\\b|void\\b|while\\b|xor\\b|yield|Countable\\b|OuterIterator\\b|RecursiveIterator\\b|SeekableIterator\\b|ArrayAccess\\b|BackedEnum\\b|Generator\\b|Iterator\\b|IteratorAggregate\\b|Serializable\\b|Stringable\\b|Throwable\\b|Traversable\\b|UnitEnum\\b|__PHP_Incomplete_Class\\b|parent\\b|php_user_filter\\b|self\\b|static\\b)[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?![A-Za-z0-9])(?![$])[ \\t\\n]*(?=(?=\\())", + "end": "\\)", + "returnBegin": true, + "contains": [ + { + "className": "title invoke__", + "begin": "[a-zA-Z0-9_\\x7f-\\xff]\\w*", + "relevance": 0 + }, + { + "begin": "\\(", + "endsWithParent": true, + "keywords": "array bool boolean float int integer new real string false FALSE null NULL true TRUE PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION ZEND_THREAD_SAFE ZEND_DEBUG_BUILD PHP_ZTS PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_OS_FAMILY PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_MIN PHP_INT_SIZE PHP_FLOAT_DIG PHP_FLOAT_EPSILON PHP_FLOAT_MIN PHP_FLOAT_MAX DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_BINARY PHP_MANDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX PHP_FD_SETSIZE E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_RECOVERABLE_ERROR E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT __COMPILER_HALT_OFFSET__ PHP_WINDOWS_EVENT_CTRL_C PHP_WINDOWS_EVENT_CTRL_BREAK PHP_CLI_PROCESS_TITLE STDERR STDIN STDOUT __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__", + "contains": [ + { + "className": "attr", + "begin": "[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?![A-Za-z0-9])(?![$])(?=:)(?=(?!::))" + }, + { + "variants": [ + { + "begin": "::(?=(?!class\\b))[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?![A-Za-z0-9])(?![$])\\b(?!\\()", + "returnBegin": true, + "contains": [ + { + "begin": "::" + }, + { + "className": "variable constant_", + "begin": "[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?![A-Za-z0-9])(?![$])\\b(?!\\()" + } + ] + }, + { + "begin": "::class", + "returnBegin": true, + "contains": [ + { + "begin": "::" + }, + { + "className": "variable language_", + "begin": "class" + } + ] + } + ] + }, + { + "$ref": "#contains.8", + "_": "variable" + }, + { + "$ref": "#contains.10.contains.3.contains.2", + "_": "comment" + }, + { + "$ref": "#contains.10.contains.3.contains.3", + "_": "string" + }, + { + "$ref": "#contains.10.contains.3.contains.4", + "_": "number" + }, + { + "$ref": "#contains.10", + "_": "closure" + }, + { + "$ref": "#contains.9", + "_": "invoke" + } + ] + } + ] }, { "className": "function", - "beginKeywords": "function", + "beginKeywords": "fn function", "end": "[;{]", "excludeEnd": true, "illegal": "\\$|\\[|%", "contains": [ + { + "beginKeywords": "use" + }, { "className": "title", "begin": "[a-zA-Z_]\\w*", "relevance": 0 }, + { + "begin": "=>", + "endsParent": true + }, { "className": "params", "begin": "\\(", "end": "\\)", - "keywords": "true false null new array", + "keywords": "array bool boolean callable float int integer iterable mixed never numeric object real string resource self static false FALSE null NULL true TRUE", "contains": [ "self", { - "$ref": "#contains.9" + "$ref": "#contains.8", + "_": "variable" }, { "className": "comment", @@ -254,27 +340,42 @@ ] }, { - "$ref": "#contains.0" + "$ref": "#contains.0", + "_": "simple-attribute" }, { - "$ref": "#contains.1" + "$ref": "#contains.1", + "_": "attribute" } ] } ] }, + { + "$ref": "#contains.9.contains.1.contains.1", + "_": "constant" + }, { "className": "class", - "beginKeywords": "class interface trait enum", - "end": "{", + "variants": [ + { + "beginKeywords": "enum", + "illegal": "[($\"]" + }, + { + "beginKeywords": "class interface trait", + "illegal": "[:($\"]" + } + ], + "end": "\\{", "excludeEnd": true, - "illegal": "[:\\(\\$\"]", "contains": [ { "beginKeywords": "extends implements" }, { - "$ref": "#contains.11.contains.0" + "$ref": "#contains.10.contains.1", + "_": "title" } ] }, @@ -284,7 +385,8 @@ "illegal": "[\\.']", "contains": [ { - "$ref": "#contains.11.contains.0" + "$ref": "#contains.10.contains.1", + "_": "title" } ] }, @@ -293,7 +395,8 @@ "end": ";", "contains": [ { - "$ref": "#contains.11.contains.0" + "$ref": "#contains.10.contains.1", + "_": "title" } ] }, @@ -301,10 +404,12 @@ "begin": "=>" }, { - "$ref": "#contains.11.contains.1.contains.3" + "$ref": "#contains.10.contains.3.contains.3", + "_": "string" }, { - "$ref": "#contains.11.contains.1.contains.4" + "$ref": "#contains.10.contains.3.contains.4", + "_": "number" } ] } diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 69b3681..f121ba3 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -115,8 +115,8 @@ public function testParseUnitBlock(string $blockName) $expected = preg_replace('/<\!\-\- REMOVE(.)+\-\->/', '', $expected); $this->assertSame( - $indenter->indent($expected), - $indenter->indent(trim($actualCrawler->filter('body')->html())) + $this->normalize($indenter->indent($expected)), + $this->normalize($indenter->indent(trim($actualCrawler->filter('body')->html()))) ); } @@ -351,6 +351,11 @@ public function testParseString() $this->assertSame($htmlString, (new DocBuilder())->buildString($rstString)->getStringResult()); } + private function normalize(string $str): string + { + return preg_replace('/\s+$/m', '', $str); + } + private function createIndenter(): Indenter { $indenter = new Indenter(); diff --git a/tests/Templates/fixtures/php.output.html b/tests/Templates/fixtures/php.output.html index b8a1b33..2ce6dcb 100644 --- a/tests/Templates/fixtures/php.output.html +++ b/tests/Templates/fixtures/php.output.html @@ -11,10 +11,10 @@ * * @Route("/blog/{slug}", name="blog_list") */ - public function list(UrlGeneratorInterface $urlGenerator, string $slug) + public function list(UrlGeneratorInterface $urlGenerator, string $slug) { - return $this->render('foo/bar.html.twig', [ - 'key' => $value + return $this->render('foo/bar.html.twig', [ + 'key' => $value ] } } \ No newline at end of file diff --git a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html index 9ea143e..2b77434 100644 --- a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html +++ b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html @@ -148,7 +148,7 @@ ; public function __construct( #[TaggedIterator('app.handlers')] - iterable $handlers, + iterable $handlers, ){ } diff --git a/tests/fixtures/expected/blocks/code-blocks/php.html b/tests/fixtures/expected/blocks/code-blocks/php.html index c005a13..f7bd021 100644 --- a/tests/fixtures/expected/blocks/code-blocks/php.html +++ b/tests/fixtures/expected/blocks/code-blocks/php.html @@ -1,4 +1,4 @@ -
+
1
 2
@@ -6,13 +6,94 @@
 4
 5
 6
-7
+7 +8 +9
// config/routes.php
 namespace Symfony\Component\Routing\Loader\Configurator;
 
-return function (RoutingConfigurator $routes) {
-    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
-        ->controller('App\Controller\CompanyController::about');
+    use App\Controller\CompanyController;
+
+return static function (RoutingConfigurator $routes): void {
+    $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us'])
+        ->controller(CompanyController::class.'::about');
 };
+
+
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+

+enum TextAlign: string implements TranslatableInterface
+{
+    case Left = 'Left aligned';
+    case Center = 'Center aligned';
+    case Right = 'Right aligned';
+
+    public function trans(TranslatorInterface $translator, ?string $locale = null): string
+    {
+        // Translate enum using custom labels
+        return match ($this) {
+            self::Left => $translator->trans('text_align.left.label', locale: $locale),
+            self::Center => $translator->trans('text_align.center.label', locale: $locale),
+            self::Right => $translator->trans('text_align.right.label', locale: $locale),
+        };
+    }
+}
+            
+        
+
+
+
+
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+

+public function getUserBadgeFrom(string $accessToken): UserBadge
+{
+    // get the data from the token
+    $payload = ...;
+
+    return new UserBadge(
+        $payload->getUserId(),
+        fn (string $userIdentifier): User => new User($userIdentifier, $payload->getRoles())
+    );
+
+    // or
+    return new UserBadge(
+        $payload->getUserId(),
+        $this->loadUser(...)
+    );
+}
+        
+
+
diff --git a/tests/fixtures/expected/blocks/nodes/literal.html b/tests/fixtures/expected/blocks/nodes/literal.html index 1c12afa..28eb3bf 100644 --- a/tests/fixtures/expected/blocks/nodes/literal.html +++ b/tests/fixtures/expected/blocks/nodes/literal.html @@ -12,8 +12,8 @@ namespace Symfony\Component\Routing\Loader\Configurator; return function (RoutingConfigurator $routes) { - $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us']) - ->controller('App\Controller\CompanyController::about'); + $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us']) + ->controller('App\Controller\CompanyController::about'); };
diff --git a/tests/fixtures/expected/main/datetime.html b/tests/fixtures/expected/main/datetime.html index c1ea089..f36ddc3 100644 --- a/tests/fixtures/expected/main/datetime.html +++ b/tests/fixtures/expected/main/datetime.html @@ -143,12 +143,10 @@

$ builder - -> - add( + -> + add( 'startDateTime' - , DateTimeType - :: - class, + , DateTimeType::class, array ( 'placeholder' @@ -417,8 +415,8 @@

$ container - -> - loadFromExtension( + -> + loadFromExtension( 'framework' , array diff --git a/tests/fixtures/source/blocks/code-blocks/php.rst b/tests/fixtures/source/blocks/code-blocks/php.rst index e9d6593..6498028 100644 --- a/tests/fixtures/source/blocks/code-blocks/php.rst +++ b/tests/fixtures/source/blocks/code-blocks/php.rst @@ -1,9 +1,49 @@ - .. code-block:: php + // config/routes.php namespace Symfony\Component\Routing\Loader\Configurator; - return function (RoutingConfigurator $routes) { + use App\Controller\CompanyController; + + return static function (RoutingConfigurator $routes): void { $routes->add('about_us', ['nl' => '/over-ons', 'en' => '/about-us']) - ->controller('App\Controller\CompanyController::about'); + ->controller(CompanyController::class.'::about'); }; + +.. code-block:: php + + enum TextAlign: string implements TranslatableInterface + { + case Left = 'Left aligned'; + case Center = 'Center aligned'; + case Right = 'Right aligned'; + + public function trans(TranslatorInterface $translator, ?string $locale = null): string + { + // Translate enum using custom labels + return match ($this) { + self::Left => $translator->trans('text_align.left.label', locale: $locale), + self::Center => $translator->trans('text_align.center.label', locale: $locale), + self::Right => $translator->trans('text_align.right.label', locale: $locale), + }; + } + } + +.. code-block:: php + + public function getUserBadgeFrom(string $accessToken): UserBadge + { + // get the data from the token + $payload = ...; + + return new UserBadge( + $payload->getUserId(), + fn (string $userIdentifier): User => new User($userIdentifier, $payload->getRoles()) + ); + + // or + return new UserBadge( + $payload->getUserId(), + $this->loadUser(...) + ); + } From a467bd93dfa28f02f5dc04bb7bfd7076cf0648a1 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 31 Jul 2024 12:13:32 +0200 Subject: [PATCH 03/17] Fix attribute arguments highlighting and better support CPP --- src/Templates/highlight.php/php.json | 4 ++-- .../blocks/code-blocks/php-attributes.html | 16 ++++++++-------- .../expected/blocks/code-blocks/php.html | 14 ++++++++++++++ tests/fixtures/source/blocks/code-blocks/php.rst | 7 +++++++ 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Templates/highlight.php/php.json b/src/Templates/highlight.php/php.json index c31251a..6f69970 100644 --- a/src/Templates/highlight.php/php.json +++ b/src/Templates/highlight.php/php.json @@ -28,7 +28,7 @@ "end": "\\)", "keywords": "array bool boolean float int integer new real string false FALSE null NULL true TRUE PHP_VERSION PHP_MAJOR_VERSION PHP_MINOR_VERSION PHP_RELEASE_VERSION PHP_VERSION_ID PHP_EXTRA_VERSION ZEND_THREAD_SAFE ZEND_DEBUG_BUILD PHP_ZTS PHP_DEBUG PHP_MAXPATHLEN PHP_OS PHP_OS_FAMILY PHP_SAPI PHP_EOL PHP_INT_MAX PHP_INT_MIN PHP_INT_SIZE PHP_FLOAT_DIG PHP_FLOAT_EPSILON PHP_FLOAT_MIN PHP_FLOAT_MAX DEFAULT_INCLUDE_PATH PEAR_INSTALL_DIR PEAR_EXTENSION_DIR PHP_EXTENSION_DIR PHP_PREFIX PHP_BINDIR PHP_BINARY PHP_MANDIR PHP_LIBDIR PHP_DATADIR PHP_SYSCONFDIR PHP_LOCALSTATEDIR PHP_CONFIG_FILE_PATH PHP_CONFIG_FILE_SCAN_DIR PHP_SHLIB_SUFFIX PHP_FD_SETSIZE E_ERROR E_WARNING E_PARSE E_NOTICE E_CORE_ERROR E_CORE_WARNING E_COMPILE_ERROR E_COMPILE_WARNING E_USER_ERROR E_USER_WARNING E_USER_NOTICE E_RECOVERABLE_ERROR E_DEPRECATED E_USER_DEPRECATED E_ALL E_STRICT __COMPILER_HALT_OFFSET__ PHP_WINDOWS_EVENT_CTRL_C PHP_WINDOWS_EVENT_CTRL_BREAK PHP_CLI_PROCESS_TITLE STDERR STDIN STDOUT __CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__", "contains": { - "$ref": "#contains.10.contains.3.contains", + "$ref": "#contains.9.contains.1.contains", "_": "params" } }, @@ -250,7 +250,7 @@ "className": "params", "begin": "\\(", "end": "\\)", - "keywords": "array bool boolean callable float int integer iterable mixed never numeric object real string resource self static false FALSE null NULL true TRUE", + "keywords": "array bool boolean callable float int integer iterable mixed never numeric object private protected public real string resource self static false FALSE null NULL true TRUE", "contains": [ "self", { diff --git a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html index 2b77434..363b21f 100644 --- a/tests/fixtures/expected/blocks/code-blocks/php-attributes.html +++ b/tests/fixtures/expected/blocks/code-blocks/php-attributes.html @@ -90,7 +90,7 @@ $ property3 ; - #[AttributeName('value', option: 'value')] + #[AttributeName('value', option: 'value')] private $ property4 @@ -102,7 +102,7 @@ ; #[AttributeName( 'value', - option: 'value' + option: 'value' )] private @@ -115,32 +115,32 @@ ; #[Assert\AttributeName( 'value', - option: 'value' + option: 'value' )] private $ property8 ; - #[Route('/blog/{page<\d+>}', name: 'blog_list')] + #[Route('/blog/{page<\d+>}', name: 'blog_list')] private $ property9 ; #[Assert\GreaterThanOrEqual( - value: 18, + value: 18, )] private $ property10 ; - #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')] + #[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')] private $ property11 ; #[Assert\AtLeastOneOf([ - new Assert\Regex('/#/'), - new Assert\Length(min: 10), + new Assert\Regex('/#/'), + new Assert\Length(min: 10), ])] private diff --git a/tests/fixtures/expected/blocks/code-blocks/php.html b/tests/fixtures/expected/blocks/code-blocks/php.html index f7bd021..163de59 100644 --- a/tests/fixtures/expected/blocks/code-blocks/php.html +++ b/tests/fixtures/expected/blocks/code-blocks/php.html @@ -97,3 +97,17 @@ +
+
+
1
+2
+3
+4
+

+public function __construct(
+    private string $username
+) {
+}
+        
+
+
diff --git a/tests/fixtures/source/blocks/code-blocks/php.rst b/tests/fixtures/source/blocks/code-blocks/php.rst index 6498028..33ed08e 100644 --- a/tests/fixtures/source/blocks/code-blocks/php.rst +++ b/tests/fixtures/source/blocks/code-blocks/php.rst @@ -47,3 +47,10 @@ $this->loadUser(...) ); } + +.. code-block:: php + + public function __construct( + private string $username + ) { + } From 8f09af6ad644414af3ed60f40a473ae4d8340f4f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 26 Aug 2024 13:07:21 +0200 Subject: [PATCH 04/17] Highlight nested PHP comments --- tests/IntegrationTest.php | 4 ++ .../code-blocks/php-nested-comments.html | 72 +++++++++++++++++++ .../code-blocks/php-nested-comments.rst | 12 ++++ 3 files changed, 88 insertions(+) create mode 100644 tests/fixtures/expected/blocks/code-blocks/php-nested-comments.html create mode 100644 tests/fixtures/source/blocks/code-blocks/php-nested-comments.rst diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index f121ba3..95fef1d 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -294,6 +294,10 @@ public function parserUnitBlockProvider() 'blockName' => 'code-blocks/php-attributes', ]; + yield 'code-block-php-nested-comments' => [ + 'blockName' => 'code-blocks/php-nested-comments', + ]; + yield 'code-block-text' => [ 'blockName' => 'code-blocks/text', ]; diff --git a/tests/fixtures/expected/blocks/code-blocks/php-nested-comments.html b/tests/fixtures/expected/blocks/code-blocks/php-nested-comments.html new file mode 100644 index 0000000..e1f7078 --- /dev/null +++ b/tests/fixtures/expected/blocks/code-blocks/php-nested-comments.html @@ -0,0 +1,72 @@ +

You can do that by adding a "stamp" to your message:

+
+
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
+            
+                use
+                Symfony
+                \
+                Component
+                \
+                Messenger
+                \
+                MessageBusInterface
+                ;
+                use
+                Symfony
+                \
+                Component
+                \
+                Messenger
+                \
+                Stamp
+                \
+                DelayStamp
+                ;
+                public
+                
+                    function
+                    index
+                    
+                        (MessageBusInterface
+                        
+                            $
+                            bus
+                        
+                        )
+                    
+                
+                {
+                
+                    $
+                    bus
+                
+                ->
+                dispatch
+                (
+                new
+                SmsNotification
+                (
+                '...'
+                ), [
+                // wait 5 seconds before processing
+                new
+                DelayStamp
+                (
+                5000
+                ), ]);
+}
+            
+        
+
+
diff --git a/tests/fixtures/source/blocks/code-blocks/php-nested-comments.rst b/tests/fixtures/source/blocks/code-blocks/php-nested-comments.rst new file mode 100644 index 0000000..ea8dc0f --- /dev/null +++ b/tests/fixtures/source/blocks/code-blocks/php-nested-comments.rst @@ -0,0 +1,12 @@ +You can do that by adding a "stamp" to your message:: + + use Symfony\Component\Messenger\MessageBusInterface; + use Symfony\Component\Messenger\Stamp\DelayStamp; + + public function index(MessageBusInterface $bus) + { + $bus->dispatch(new SmsNotification('...'), [ + // wait 5 seconds before processing + new DelayStamp(5000), + ]); + } From e7c0a063f5eba8f3a5a279cf1a6b9305078c59ff Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 1 Aug 2024 20:03:55 +0200 Subject: [PATCH 05/17] :bug: Fix yaml number rendering --- src/Renderers/CodeNodeRenderer.php | 1 + src/Templates/highlight.php/yaml.json | 127 ++++++++++++++++++ .../expected/blocks/code-blocks/yaml.html | 37 ++++- .../source/blocks/code-blocks/yaml.rst | 9 ++ 4 files changed, 170 insertions(+), 4 deletions(-) create mode 100644 src/Templates/highlight.php/yaml.json diff --git a/src/Renderers/CodeNodeRenderer.php b/src/Renderers/CodeNodeRenderer.php index a9e5643..d5e771e 100644 --- a/src/Renderers/CodeNodeRenderer.php +++ b/src/Renderers/CodeNodeRenderer.php @@ -121,6 +121,7 @@ private function configureHighlighter() if (false === self::$isHighlighterConfigured) { Highlighter::registerLanguage('php', __DIR__.'/../Templates/highlight.php/php.json', true); Highlighter::registerLanguage('twig', __DIR__.'/../Templates/highlight.php/twig.json', true); + Highlighter::registerLanguage('yaml', __DIR__.'/../Templates/highlight.php/yaml.json', true); } self::$isHighlighterConfigured = true; diff --git a/src/Templates/highlight.php/yaml.json b/src/Templates/highlight.php/yaml.json new file mode 100644 index 0000000..3db70a8 --- /dev/null +++ b/src/Templates/highlight.php/yaml.json @@ -0,0 +1,127 @@ +{ + "case_insensitive": true, + "aliases": [ + "yml", + "YAML", + "yaml" + ], + "contains": [ + { + "className": "attr", + "variants": [ + { + "begin": "\\w[\\w :\\\/.-]*:(?=[ \t]|$)" + }, + { + "begin": "\"\\w[\\w :\\\/.-]*\":(?=[ \t]|$)" + }, + { + "begin": "'\\w[\\w :\\\/.-]*':(?=[ \t]|$)" + } + ] + }, + { + "className": "meta", + "begin": "^---s*$", + "relevance": 10 + }, + { + "className": "string", + "begin": "[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*" + }, + { + "begin": "<%[%=-]?", + "end": "[%-]?%>", + "subLanguage": "ruby", + "excludeBegin": true, + "excludeEnd": true, + "relevance": 0 + }, + { + "className": "type", + "begin": "![a-zA-Z_]\\w*" + }, + { + "className": "type", + "begin": "!![a-zA-Z_]\\w*" + }, + { + "className": "meta", + "begin": "&[a-zA-Z_]\\w*$" + }, + { + "className": "meta", + "begin": "\\*[a-zA-Z_]\\w*$" + }, + { + "className": "bullet", + "begin": "\\-(?=[ ]|$)", + "relevance": 0 + }, + { + "className": "comment", + "begin": "#", + "end": "$", + "contains": [ + { + "begin": "\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b" + }, + { + "className": "doctag", + "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", + "relevance": 0 + } + ] + }, + { + "beginKeywords": "true false yes no null", + "keywords": { + "literal": "true false yes no null" + } + }, + { + "className": "number", + "begin": "\\b([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(([Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(\\.([0-9]*))?([ \\t]*(Z|([-+])([0-9][0-9]?)(:([0-9][0-9]))?))?)?\\b" + }, + { + "className": "number", + "begin": "(-?)(\\b0[xX][a-fA-F0-9_]+|(\\b\\d[\\d_]*(\\.[\\d_]*)?|\\.\\d[\\d_]*)([eE][-+]?\\d[\\d_]*)?)\\b" + }, + { + "className": "string", + "relevance": 0, + "variants": [ + { + "begin": "'", + "end": "'" + }, + { + "begin": "\"", + "end": "\"" + }, + { + "begin": "\\S+" + } + ], + "contains": [ + { + "begin": "\\\\[\\s\\S]", + "relevance": 0 + }, + { + "className": "template-variable", + "variants": [ + { + "begin": "{{", + "end": "}}" + }, + { + "begin": "%{", + "end": "}" + } + ] + } + ] + } + ] +} diff --git a/tests/fixtures/expected/blocks/code-blocks/yaml.html b/tests/fixtures/expected/blocks/code-blocks/yaml.html index fceca11..2de3b7b 100644 --- a/tests/fixtures/expected/blocks/code-blocks/yaml.html +++ b/tests/fixtures/expected/blocks/code-blocks/yaml.html @@ -1,7 +1,36 @@ -
+
-
1
-
# some code
-
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
+            
+                # some code
+                parameters:
+                credit_card_number:
+                1234_5678_9012_3456
+                long_number:
+                10_000_000_000
+                pi:
+                3.14159_26535_89793
+                hex_words:
+                0x_CAFE_F00D
+                canonical:
+                2001-12-15T02:59:43.1Z
+                iso8601:
+                2001-12-14t21:59:43.10-05:00
+                spaced:
+                2001-12-14 21:59:43.10 -5
+                date:
+                2002-12-14
+            
+        
diff --git a/tests/fixtures/source/blocks/code-blocks/yaml.rst b/tests/fixtures/source/blocks/code-blocks/yaml.rst index 45ce98d..f56652d 100644 --- a/tests/fixtures/source/blocks/code-blocks/yaml.rst +++ b/tests/fixtures/source/blocks/code-blocks/yaml.rst @@ -1,3 +1,12 @@ .. code-block:: yaml # some code + parameters: + credit_card_number: 1234_5678_9012_3456 + long_number: 10_000_000_000 + pi: 3.14159_26535_89793 + hex_words: 0x_CAFE_F00D + canonical: 2001-12-15T02:59:43.1Z + iso8601: 2001-12-14t21:59:43.10-05:00 + spaced: 2001-12-14 21:59:43.10 -5 + date: 2002-12-14 From 3a300ac19a9338c4e05fd1a8434309eb83805269 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 11 Sep 2024 11:19:33 +0200 Subject: [PATCH 06/17] Add support for tilde characters --- tests/IntegrationTest.php | 4 ++++ tests/fixtures/expected/blocks/nodes/text.html | 7 +++++++ tests/fixtures/source/blocks/nodes/text.rst | 7 +++++++ 3 files changed, 18 insertions(+) create mode 100644 tests/fixtures/expected/blocks/nodes/text.html create mode 100644 tests/fixtures/source/blocks/nodes/text.rst diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index f121ba3..3045334 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -142,6 +142,10 @@ public function parserUnitBlockProvider() 'blockName' => 'nodes/span-link', ]; + yield 'text' => [ + 'blockName' => 'nodes/text', + ]; + yield 'title' => [ 'blockName' => 'nodes/title', ]; diff --git a/tests/fixtures/expected/blocks/nodes/text.html b/tests/fixtures/expected/blocks/nodes/text.html new file mode 100644 index 0000000..afc3337 --- /dev/null +++ b/tests/fixtures/expected/blocks/nodes/text.html @@ -0,0 +1,7 @@ +

Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ut enim ad minim +veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea +commodo consequat. Duis aute irure dolor in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur.

+ +

Excepteur ~1,000 sint! Occaecat cupidatat non proident, sunt in culpa qui officia +deserunt mollit anim id est laborum. áàâäãåéèêëíìîïóòôöõúùûüñçÿ

diff --git a/tests/fixtures/source/blocks/nodes/text.rst b/tests/fixtures/source/blocks/nodes/text.rst new file mode 100644 index 0000000..f5dbb33 --- /dev/null +++ b/tests/fixtures/source/blocks/nodes/text.rst @@ -0,0 +1,7 @@ +**Lorem ipsum** dolor sit amet, consectetur adipisicing elit. Ut enim ad minim +veniam, quis nostrud *exercitation ullamco laboris* nisi ut aliquip ex ea +commodo consequat. ``Duis aute irure dolor`` in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur. + +Excepteur ~1,000 sint! Occaecat cupidatat non proident, sunt in culpa qui officia +deserunt mollit anim id est laborum. áàâäãåéèêëíìîïóòôöõúùûüñçÿ From 9223ccc89e6c7b0ab78c0af755ce85ebaa918668 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 11 Sep 2024 15:51:17 +0200 Subject: [PATCH 07/17] Temporary replace tildes to avoid it being parsed as NBSP --- src/Renderers/SpanNodeRenderer.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/Renderers/SpanNodeRenderer.php b/src/Renderers/SpanNodeRenderer.php index 65598bd..f9db721 100644 --- a/src/Renderers/SpanNodeRenderer.php +++ b/src/Renderers/SpanNodeRenderer.php @@ -42,6 +42,19 @@ public function __construct( $this->symfonyVersion = $symfonyVersion; } + public function render(): string + { + // Work around "~" being parsed as non-breaking space by rst-parser, + // while this is not part of the specification. + $spanValue = $this->span->getValue(); + $spanValue = str_replace('~', '__TILDE__', $spanValue); + $this->span->setValue($spanValue); + + $rendered = parent::render(); + + return str_replace('__TILDE__', '~', $rendered); + } + /** @inheritDoc */ public function link(?string $url, string $title, array $attributes = []): string { From caacb35c69edfe26451c4bb6e3cabb4156938c07 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Sep 2024 11:27:42 +0200 Subject: [PATCH 08/17] Minor tweak --- src/Renderers/SpanNodeRenderer.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Renderers/SpanNodeRenderer.php b/src/Renderers/SpanNodeRenderer.php index f9db721..927c3fa 100644 --- a/src/Renderers/SpanNodeRenderer.php +++ b/src/Renderers/SpanNodeRenderer.php @@ -47,6 +47,11 @@ public function render(): string // Work around "~" being parsed as non-breaking space by rst-parser, // while this is not part of the specification. $spanValue = $this->span->getValue(); + + if (str_contains($spanValue, '__TILDE__')) { + throw new \Exception('Cannot render content containing the text "__TILDE__" as it is used as a special placeholder in the build.'); + } + $spanValue = str_replace('~', '__TILDE__', $spanValue); $this->span->setValue($spanValue); From f34b7a73d98a77db5b492c9a53fe8d520cda8279 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Sep 2024 12:03:00 +0200 Subject: [PATCH 09/17] Don't use the deprecated spaceless filter --- src/Templates/default/html/figure.html.twig | 8 +------- src/Templates/default/html/link.html.twig | 2 -- src/Templates/default/html/toc-level.html.twig | 12 +++++------- src/Templates/default/html/toc.html.twig | 10 ++++------ tests/fixtures/expected/build-pdf/book.html | 4 ++-- tests/fixtures/expected/main/index.html | 2 +- tests/fixtures/expected/toctree/index.html | 10 +++++----- 7 files changed, 18 insertions(+), 30 deletions(-) diff --git a/src/Templates/default/html/figure.html.twig b/src/Templates/default/html/figure.html.twig index e1786c0..5836788 100644 --- a/src/Templates/default/html/figure.html.twig +++ b/src/Templates/default/html/figure.html.twig @@ -1,12 +1,7 @@ {# Overridden to fix lack of figclass support (class attribute on +
{{ figureNode.image.render()|raw }} {% if figureNode.document %} @@ -17,4 +12,3 @@ Overridden to fix lack of figclass support (class attribute on -{% endapply %} diff --git a/src/Templates/default/html/link.html.twig b/src/Templates/default/html/link.html.twig index 8b9ca5b..7c82a66 100644 --- a/src/Templates/default/html/link.html.twig +++ b/src/Templates/default/html/link.html.twig @@ -1,5 +1,3 @@ -{% apply spaceless %} {% set domElement = attributes.domElement|default %} {% set class = (attributes.class|default ? attributes.class ~ ' ' : '') ~ 'reference ' ~ (('://' in url) ? 'external' : 'internal') %} key != 'domElement' and key != 'class') %} {{ key }}="{{ value }}"{% endfor %}>{% if domElement %}<{{ domElement }}>{% endif %}{{ title|raw }}{% if domElement %}{% endif %} -{% endapply %} diff --git a/src/Templates/default/html/toc-level.html.twig b/src/Templates/default/html/toc-level.html.twig index 1bdaef8..8c3eb34 100644 --- a/src/Templates/default/html/toc-level.html.twig +++ b/src/Templates/default/html/toc-level.html.twig @@ -1,7 +1,5 @@ -{% apply spaceless %} -
    - {% for tocItem in tocItems %} - {% include "toc-item.html.twig" with { toc_deep_level: 1 } %} - {% endfor %} -
-{% endapply %} +
    + {% for tocItem in tocItems %} + {% include "toc-item.html.twig" with { toc_deep_level: 1 } %} + {% endfor %} +
diff --git a/src/Templates/default/html/toc.html.twig b/src/Templates/default/html/toc.html.twig index 55b8737..8b9c883 100644 --- a/src/Templates/default/html/toc.html.twig +++ b/src/Templates/default/html/toc.html.twig @@ -1,6 +1,4 @@ -{% apply spaceless %} - {% set toc_options = toc_options(tocItems) %} -
- {% include "toc-level.html.twig" %} -
-{% endapply %} +{% set toc_options = toc_options(tocItems) %} +
+ {% include "toc-level.html.twig" %} +
diff --git a/tests/fixtures/expected/build-pdf/book.html b/tests/fixtures/expected/build-pdf/book.html index a214463..4454f94 100644 --- a/tests/fixtures/expected/build-pdf/book.html +++ b/tests/fixtures/expected/build-pdf/book.html @@ -8,8 +8,8 @@

Book

Here is a link to the main index

diff --git a/tests/fixtures/expected/main/index.html b/tests/fixtures/expected/main/index.html index 1346373..628cc91 100644 --- a/tests/fixtures/expected/main/index.html +++ b/tests/fixtures/expected/main/index.html @@ -10,7 +10,7 @@

Some Test Docs!

- +

A header

diff --git a/tests/fixtures/expected/toctree/index.html b/tests/fixtures/expected/toctree/index.html index e07a28e..676005a 100644 --- a/tests/fixtures/expected/toctree/index.html +++ b/tests/fixtures/expected/toctree/index.html @@ -9,11 +9,11 @@ From b4a10315d9e2074d490a01cb78706e0015b65b60 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 26 Sep 2024 22:09:28 +0200 Subject: [PATCH 10/17] Enhancement: Drop PHP 7.4 support (#183) --- .github/workflows/ci.yaml | 4 ++-- composer.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index bc16178..4db2db0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -20,7 +20,7 @@ jobs: uses: shivammathur/setup-php@v2 with: coverage: none - php-version: 7.4 + php-version: 8.3 tools: composer:v2 ini-values: date.timezone=UTC @@ -37,7 +37,7 @@ jobs: # add here only the PHP versions and OS used in GitHub CI (for tests) # and on the symfony.com server (where the Symfony Docs are built) operating-system: ['ubuntu-latest'] - php-version: ['7.4', '8.3'] + php-version: ['8.3'] steps: - name: 'Checkout code' diff --git a/composer.json b/composer.json index dde5a06..8e66ada 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } }, "require": { - "php": ">=7.4", + "php": ">=8.3", "ext-json": "*", "ext-curl": "*", "doctrine/rst-parser": "^0.5", From 126cfbff31822a56f39935f64d8da06265804a2b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 27 Sep 2024 09:31:34 +0200 Subject: [PATCH 11/17] Add support for inline Twig comments Co-authored-by: Wouter de Jong --- src/Templates/highlight.php/twig.json | 18 +++++++++-- .../expected/blocks/code-blocks/twig.html | 30 +++++++++++++++++-- .../source/blocks/code-blocks/twig.rst | 10 ++++++- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/Templates/highlight.php/twig.json b/src/Templates/highlight.php/twig.json index b961028..ceb675d 100644 --- a/src/Templates/highlight.php/twig.json +++ b/src/Templates/highlight.php/twig.json @@ -25,6 +25,12 @@ "begin": "\\{%", "end": "%}", "contains": [ + { + "className": "comment", + "begin": "#", + "end": "$", + "endsWithParent": true + }, { "className": "name", "begin": "\\w+", @@ -32,6 +38,9 @@ "starts": { "endsWithParent": true, "contains": [ + { + "$ref": "#contains.1.contains.0" + }, { "begin": "\\|[A-Za-z_]+:?", "keywords": "abs batch capitalize column convert_encoding date date_modify default escape filter first format inky_to_html inline_css join json_encode keys last length lower map markdown merge nl2br number_format raw reduce replace reverse round slice sort spaceless split striptags title trim upper url_encode", @@ -53,7 +62,7 @@ ] }, { - "$ref": "#contains.1.contains.0.starts.contains.0.contains.0" + "$ref": "#contains.1.contains.1.starts.contains.1.contains.0" } ], "relevance": 0 @@ -68,10 +77,13 @@ "contains": [ "self", { - "$ref": "#contains.1.contains.0.starts.contains.0" + "$ref": "#contains.1.contains.0" + }, + { + "$ref": "#contains.1.contains.1.starts.contains.1" }, { - "$ref": "#contains.1.contains.0.starts.contains.0.contains.0" + "$ref": "#contains.1.contains.1.starts.contains.1.contains.0" } ] } diff --git a/tests/fixtures/expected/blocks/code-blocks/twig.html b/tests/fixtures/expected/blocks/code-blocks/twig.html index fab139d..83c841c 100644 --- a/tests/fixtures/expected/blocks/code-blocks/twig.html +++ b/tests/fixtures/expected/blocks/code-blocks/twig.html @@ -1,6 +1,30 @@ -
+
-
1
-
{# some code #}
+
1
+2
+3
+4
+5
+6
+7
+8
+9
+
+            
+                {# some code #}
+                
+                
+                    {%
+                        set some_var = 'some value' # some inline comment
+                    %}
+                
+                
+                {{
+                    # another inline comment
+                    'Lorem Ipsum'|uppercase
+                    # final inline comment
+                }}
+            
+        
diff --git a/tests/fixtures/source/blocks/code-blocks/twig.rst b/tests/fixtures/source/blocks/code-blocks/twig.rst index 01d0685..229041d 100644 --- a/tests/fixtures/source/blocks/code-blocks/twig.rst +++ b/tests/fixtures/source/blocks/code-blocks/twig.rst @@ -1,3 +1,11 @@ - .. code-block:: twig + {# some code #} + {% + set some_var = 'some value' # some inline comment + %} + {{ + # another inline comment + 'Lorem Ipsum'|uppercase + # final inline comment + }} From d05cf4202737306c383016e18f6454865a2492a1 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Dec 2024 11:19:15 +0100 Subject: [PATCH 12/17] Fix PHP 8.4 deprecations --- src/Renderers/SpanNodeRenderer.php | 2 +- src/SymfonyHTMLFormat.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Renderers/SpanNodeRenderer.php b/src/Renderers/SpanNodeRenderer.php index 927c3fa..e1e7775 100644 --- a/src/Renderers/SpanNodeRenderer.php +++ b/src/Renderers/SpanNodeRenderer.php @@ -32,7 +32,7 @@ public function __construct( SpanNode $span, BaseSpanNodeRenderer $decoratedSpanNodeRenderer, ?UrlChecker $urlChecker = null, - string $symfonyVersion = null + ?string $symfonyVersion = null ) { parent::__construct($environment, $span); diff --git a/src/SymfonyHTMLFormat.php b/src/SymfonyHTMLFormat.php index 9c17ca9..16ea957 100644 --- a/src/SymfonyHTMLFormat.php +++ b/src/SymfonyHTMLFormat.php @@ -29,7 +29,7 @@ final class SymfonyHTMLFormat implements Format private $urlChecker; private $symfonyVersion; - public function __construct(TemplateRenderer $templateRenderer, Format $HTMLFormat, ?UrlChecker $urlChecker = null, string $symfonyVersion = null) + public function __construct(TemplateRenderer $templateRenderer, Format $HTMLFormat, ?UrlChecker $urlChecker = null, ?string $symfonyVersion = null) { $this->templateRenderer = $templateRenderer; $this->htmlFormat = $HTMLFormat; From f05792a72a09602f9c992d40d00c205b8d139ab9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Dec 2024 12:37:03 +0100 Subject: [PATCH 13/17] Fix a Twig deprecation (#186) --- src/Templates/default/html/image.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Templates/default/html/image.html.twig b/src/Templates/default/html/image.html.twig index f7ff3ff..14f090e 100644 --- a/src/Templates/default/html/image.html.twig +++ b/src/Templates/default/html/image.html.twig @@ -2,7 +2,7 @@ Overridden so we can control the path to the image based on our copying logic. See CopyImagesListener. #} -{% set wrap_image_with_browser = 'with-browser' in imageNode.options.class ?? '' %} +{% set wrap_image_with_browser = 'with-browser' in (imageNode.options.class ?? '') %} {% if wrap_image_with_browser %}
{% endif %} {% if wrap_image_with_browser %}
{% endif %} From b5a4aed0e702ce8cc30a82632e9dc6775d54510f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Dec 2024 13:41:00 +0100 Subject: [PATCH 14/17] Test code in PHP 8.4 too (#187) --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4db2db0..f85af4b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,7 +37,7 @@ jobs: # add here only the PHP versions and OS used in GitHub CI (for tests) # and on the symfony.com server (where the Symfony Docs are built) operating-system: ['ubuntu-latest'] - php-version: ['8.3'] + php-version: ['8.3', '8.4'] steps: - name: 'Checkout code' From af7ee47654250144e2c41b7ee9f869d50a7196a1 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 31 Dec 2024 15:49:09 +0100 Subject: [PATCH 15/17] Allow one line comments in argument list --- src/Templates/highlight.php/php.json | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Templates/highlight.php/php.json b/src/Templates/highlight.php/php.json index 6f69970..0db2cb8 100644 --- a/src/Templates/highlight.php/php.json +++ b/src/Templates/highlight.php/php.json @@ -204,7 +204,15 @@ "_": "variable" }, { - "$ref": "#contains.10.contains.3.contains.2", + "$ref": "#contains.3", + "_": "comment" + }, + { + "$ref": "#contains.4", + "_": "comment" + }, + { + "$ref": "#contains.5", "_": "comment" }, { @@ -258,19 +266,8 @@ "_": "variable" }, { - "className": "comment", - "begin": "/\\*", - "end": "\\*/", - "contains": [ - { - "$ref": "#contains.2.contains.0" - }, - { - "className": "doctag", - "begin": "(?:TODO|FIXME|NOTE|BUG|XXX):", - "relevance": 0 - } - ] + "$ref": "#contains.5", + "_": "comment" }, { "className": "string", From 9a75cd7ebc7b195831b1a9f218e34c3da6d8fa24 Mon Sep 17 00:00:00 2001 From: Antoine Lamirault Date: Thu, 20 Mar 2025 21:44:07 +0100 Subject: [PATCH 16/17] Add support for phpclass reference with namespace --- src/Reference/PhpClassReference.php | 3 ++- tests/fixtures/expected/blocks/references/php-class.html | 1 + tests/fixtures/source/blocks/references/php-class.rst | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Reference/PhpClassReference.php b/src/Reference/PhpClassReference.php index 4e104e1..0bb0ba8 100644 --- a/src/Reference/PhpClassReference.php +++ b/src/Reference/PhpClassReference.php @@ -29,10 +29,11 @@ public function getName(): string public function resolve(Environment $environment, string $data): ResolvedReference { + $classnamePath = str_replace('\\', '-', strtolower($data)); return new ResolvedReference( $environment->getCurrentFileName(), $data, - sprintf('%s/class.%s.php', $this->phpDocUrl, strtolower($data)), + sprintf('%s/class.%s.php', $this->phpDocUrl, $classnamePath), [], [ 'title' => $data, diff --git a/tests/fixtures/expected/blocks/references/php-class.html b/tests/fixtures/expected/blocks/references/php-class.html index 271b968..b1e018e 100644 --- a/tests/fixtures/expected/blocks/references/php-class.html +++ b/tests/fixtures/expected/blocks/references/php-class.html @@ -1 +1,2 @@

ArrayAccess

+

BcMath\Number

diff --git a/tests/fixtures/source/blocks/references/php-class.rst b/tests/fixtures/source/blocks/references/php-class.rst index 5708c64..f0782b4 100644 --- a/tests/fixtures/source/blocks/references/php-class.rst +++ b/tests/fixtures/source/blocks/references/php-class.rst @@ -1,2 +1,4 @@ :phpclass:`ArrayAccess` + +:phpclass:`BcMath\Number` From 44b5818ee8c238b07ec8a16f8a863ed644d0b8f5 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 7 Apr 2025 13:02:32 +0200 Subject: [PATCH 17/17] Make behavior of PHP and GitHub references consistent (#191) --- src/Reference/MethodReference.php | 11 +++++------ src/Reference/PhpClassReference.php | 10 ++++++---- src/Reference/PhpMethodReference.php | 15 +++++++++++---- .../expected/blocks/references/php-class.html | 2 +- .../expected/blocks/references/php-method.html | 3 ++- tests/fixtures/expected/main/datetime.html | 2 +- .../source/blocks/references/php-class.rst | 2 +- .../source/blocks/references/php-method.rst | 2 ++ 8 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/Reference/MethodReference.php b/src/Reference/MethodReference.php index 632aaa2..b068f33 100644 --- a/src/Reference/MethodReference.php +++ b/src/Reference/MethodReference.php @@ -30,20 +30,19 @@ public function getName(): string public function resolve(Environment $environment, string $data): ResolvedReference { - $className = explode('::', $data)[0]; - $className = str_replace('\\\\', '\\', $className); - - if (!u($data)->containsAny('::')) { + $data = u($data); + if (!$data->containsAny('::')) { throw new \RuntimeException(sprintf('Malformed method reference "%s" in file "%s"', $data, $environment->getCurrentFileName())); } - $methodName = explode('::', $data)[1]; + [$className, $methodName] = $data->split('::', 2); + $className = $className->replace('\\\\', '\\'); $scrollTextFragment = sprintf('#:~:text=%s', rawurlencode('function '.$methodName)); return new ResolvedReference( $environment->getCurrentFileName(), $methodName.'()', - sprintf('%s/%s.php%s', $this->symfonyRepositoryUrl, str_replace('\\', '/', $className), $scrollTextFragment), + sprintf('%s/%s.php%s', $this->symfonyRepositoryUrl, $className->replace('\\', '/'), $scrollTextFragment), [], [ 'title' => sprintf('%s::%s()', $className, $methodName), diff --git a/src/Reference/PhpClassReference.php b/src/Reference/PhpClassReference.php index 0bb0ba8..fbaabe4 100644 --- a/src/Reference/PhpClassReference.php +++ b/src/Reference/PhpClassReference.php @@ -12,6 +12,7 @@ use Doctrine\RST\Environment; use Doctrine\RST\References\Reference; use Doctrine\RST\References\ResolvedReference; +use function Symfony\Component\String\u; class PhpClassReference extends Reference { @@ -29,14 +30,15 @@ public function getName(): string public function resolve(Environment $environment, string $data): ResolvedReference { - $classnamePath = str_replace('\\', '-', strtolower($data)); + $className = u($data)->replace('\\\\', '\\'); + return new ResolvedReference( $environment->getCurrentFileName(), - $data, - sprintf('%s/class.%s.php', $this->phpDocUrl, $classnamePath), + $className->afterLast('\\'), + sprintf('%s/class.%s.php', $this->phpDocUrl, $className->replace('\\', '-')->lower()), [], [ - 'title' => $data, + 'title' => $className, ] ); } diff --git a/src/Reference/PhpMethodReference.php b/src/Reference/PhpMethodReference.php index ac53744..9a85a91 100644 --- a/src/Reference/PhpMethodReference.php +++ b/src/Reference/PhpMethodReference.php @@ -12,6 +12,7 @@ use Doctrine\RST\Environment; use Doctrine\RST\References\Reference; use Doctrine\RST\References\ResolvedReference; +use function Symfony\Component\String\u; class PhpMethodReference extends Reference { @@ -29,15 +30,21 @@ public function getName(): string public function resolve(Environment $environment, string $data): ResolvedReference { - [$class, $method] = explode('::', $data, 2); + $data = u($data); + if (!$data->containsAny('::')) { + throw new \RuntimeException(sprintf('Malformed method reference "%s" in file "%s"', $data, $environment->getCurrentFileName())); + } + + [$className, $methodName] = $data->split('::', 2); + $className = $className->replace('\\\\', '\\'); return new ResolvedReference( $environment->getCurrentFileName(), - $data.'()', - sprintf('%s/%s.%s.php', $this->phpDocUrl, strtolower($class), strtolower($method)), + $methodName.'()', + sprintf('%s/%s.%s.php', $this->phpDocUrl, $className->replace('\\', '-')->lower(), $methodName->lower()), [], [ - 'title' => $class, + 'title' => sprintf('%s::%s()', $className, $methodName), ] ); } diff --git a/tests/fixtures/expected/blocks/references/php-class.html b/tests/fixtures/expected/blocks/references/php-class.html index b1e018e..a91b1fd 100644 --- a/tests/fixtures/expected/blocks/references/php-class.html +++ b/tests/fixtures/expected/blocks/references/php-class.html @@ -1,2 +1,2 @@

ArrayAccess

-

BcMath\Number

+

Number

diff --git a/tests/fixtures/expected/blocks/references/php-method.html b/tests/fixtures/expected/blocks/references/php-method.html index e86c571..59323ad 100644 --- a/tests/fixtures/expected/blocks/references/php-method.html +++ b/tests/fixtures/expected/blocks/references/php-method.html @@ -1 +1,2 @@ -

Locale::getDefault()

+

getDefault()

+

add()

diff --git a/tests/fixtures/expected/main/datetime.html b/tests/fixtures/expected/main/datetime.html index f36ddc3..d6892fa 100644 --- a/tests/fixtures/expected/main/datetime.html +++ b/tests/fixtures/expected/main/datetime.html @@ -79,7 +79,7 @@

methods: doRequest(). Or a namespace: Constraints. Or a PHP function: parse_ini_file. -Or a PHP method! Locale::getDefault().

+Or a PHP method! getDefault().

diff --git a/tests/fixtures/source/blocks/references/php-class.rst b/tests/fixtures/source/blocks/references/php-class.rst index f0782b4..284a901 100644 --- a/tests/fixtures/source/blocks/references/php-class.rst +++ b/tests/fixtures/source/blocks/references/php-class.rst @@ -1,4 +1,4 @@ :phpclass:`ArrayAccess` -:phpclass:`BcMath\Number` +:phpclass:`BcMath\\Number` diff --git a/tests/fixtures/source/blocks/references/php-method.rst b/tests/fixtures/source/blocks/references/php-method.rst index 11705cd..26d782d 100644 --- a/tests/fixtures/source/blocks/references/php-method.rst +++ b/tests/fixtures/source/blocks/references/php-method.rst @@ -1,2 +1,4 @@ :phpmethod:`Locale::getDefault` + +:phpmethod:`BcMath\\Number::add`