Skip to content

Commit

Permalink
feature #173 Update the php syntax file to highlight attributes (javi…
Browse files Browse the repository at this point in the history
…ereguiluz, wouterj)

This PR was merged into the main branch.

Discussion
----------

Update the php syntax file to highlight attributes

Alternative to #172 (as per my suggestion).

`@javiereguiluz` what do you think of this? The output is slightly different from yours, but that's how highlight.js works :)

I tried my suggestion of converting the latest highlight.js syntax file, this unfortunately didn't work (there are too many BC breaks in v10). So I've copy pasted their regex and used it to what is available in our syntax file already.

If we want to go this way, I can also follow up with a PR adding more support for PHP features (e.g. arrow functions). For now, I've just added a couple keywords that plainly were missing (such as trait and enum).

Commits
-------

020a281 Add support for PHP attributes
9764478 Add tests for highlighting PHP attributes
  • Loading branch information
javiereguiluz committed May 20, 2024
2 parents 35ae0d5 + 020a281 commit 81e707a
Show file tree
Hide file tree
Showing 4 changed files with 233 additions and 17 deletions.
50 changes: 33 additions & 17 deletions src/Templates/highlight.php/php.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,23 @@
"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 switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",
"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])(?![$])",
"end": "]",
"contains": [
{
"begin": "\\(",
"end": "\\)",
"keywords": "true false null new array",
"contains": {
"$ref": "#contains.10.contains.1.contains"
}
}
]
},
{
"className": "comment",
"begin": "#",
Expand All @@ -35,7 +50,7 @@
"begin": "<\\?(php)?|\\?>"
},
{
"$ref": "#contains.0.contains.0"
"$ref": "#contains.1.contains.0"
},
{
"className": "doctag",
Expand All @@ -54,7 +69,7 @@
"begin": "@[A-Za-z]+"
},
{
"$ref": "#contains.0.contains.0"
"$ref": "#contains.1.contains.0"
},
{
"className": "doctag",
Expand All @@ -69,7 +84,7 @@
"end": false,
"contains": [
{
"$ref": "#contains.0.contains.0"
"$ref": "#contains.1.contains.0"
},
{
"className": "doctag",
Expand Down Expand Up @@ -105,7 +120,7 @@
]
},
{
"$ref": "#contains.1.contains.0"
"$ref": "#contains.2.contains.0"
},
{
"className": "variable",
Expand Down Expand Up @@ -137,18 +152,19 @@
"className": "params",
"begin": "\\(",
"end": "\\)",
"keywords": "true false null new array",
"contains": [
"self",
{
"$ref": "#contains.7"
"$ref": "#contains.8"
},
{
"className": "comment",
"begin": "/\\*",
"end": "\\*/",
"contains": [
{
"$ref": "#contains.0.contains.0"
"$ref": "#contains.1.contains.0"
},
{
"className": "doctag",
Expand All @@ -161,10 +177,10 @@
"className": "string",
"contains": [
{
"$ref": "#contains.4.contains.0"
"$ref": "#contains.5.contains.0"
},
{
"$ref": "#contains.1.contains.0"
"$ref": "#contains.2.contains.0"
}
],
"variants": [
Expand All @@ -183,7 +199,7 @@
"illegal": null,
"contains": [
{
"$ref": "#contains.4.contains.0"
"$ref": "#contains.5.contains.0"
}
]
},
Expand All @@ -194,7 +210,7 @@
"illegal": null,
"contains": [
{
"$ref": "#contains.4.contains.0"
"$ref": "#contains.5.contains.0"
},
{
"className": "subst",
Expand Down Expand Up @@ -230,7 +246,7 @@
},
{
"className": "class",
"beginKeywords": "class interface",
"beginKeywords": "class interface trait enum",
"end": "{",
"excludeEnd": true,
"illegal": "[:\\(\\$\"]",
Expand All @@ -239,7 +255,7 @@
"beginKeywords": "extends implements"
},
{
"$ref": "#contains.9.contains.0"
"$ref": "#contains.10.contains.0"
}
]
},
Expand All @@ -249,7 +265,7 @@
"illegal": "[\\.']",
"contains": [
{
"$ref": "#contains.9.contains.0"
"$ref": "#contains.10.contains.0"
}
]
},
Expand All @@ -258,18 +274,18 @@
"end": ";",
"contains": [
{
"$ref": "#contains.9.contains.0"
"$ref": "#contains.10.contains.0"
}
]
},
{
"begin": "=>"
},
{
"$ref": "#contains.9.contains.1.contains.3"
"$ref": "#contains.10.contains.1.contains.3"
},
{
"$ref": "#contains.9.contains.1.contains.4"
"$ref": "#contains.10.contains.1.contains.4"
}
]
}
4 changes: 4 additions & 0 deletions tests/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ public function parserUnitBlockProvider()
'blockName' => 'code-blocks/php-annotations',
];

yield 'code-block-php-attributes' => [
'blockName' => 'code-blocks/php-attributes',
];

yield 'code-block-text' => [
'blockName' => 'code-blocks/text',
];
Expand Down
140 changes: 140 additions & 0 deletions tests/fixtures/expected/blocks/code-blocks/php-attributes.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<div translate="no" data-loc="54" class="notranslate codeblock codeblock-length-md codeblock-php-attributes codeblock-php">
<div class="codeblock-scroll">
<pre class="codeblock-lines">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54</pre>
<pre class="codeblock-code">
<code>
<span class="hljs-comment">// src/SomePath/SomeClass.php</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">App</span>\<span class="hljs-title">SomePath</span>;
<span class="hljs-keyword">use</span><span class="hljs-title">Symfony</span>\<span class="hljs-title">Component</span>\<span class="hljs-title">Validator</span>\<span class="hljs-title">Constraints</span> <span class="hljs-title">as</span> <span class="hljs-title">Assert</span>;
<span class="hljs-class">
<span class="hljs-keyword">class</span>
<span class="hljs-title">SomeClass</span>
</span>
{
<span class="hljs-php-attribute">#[AttributeName]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property1</span>
;
<span class="hljs-php-attribute">#[AttributeName()]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property2</span>
;
<span class="hljs-php-attribute">#[AttributeName(<span class="hljs-string">'value'</span>)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property3</span>
;
<span class="hljs-php-attribute">#[AttributeName(<span class="hljs-string">'value'</span>, option: <span class="hljs-string">'value'</span>)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property4</span>
;
<span class="hljs-php-attribute">#[AttributeName([<span class="hljs-string">'value'</span> =&gt; <span class="hljs-string">'value'</span>])]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property5</span>
;
<span class="hljs-php-attribute">#[AttributeName(
<span class="hljs-string">'value'</span>,
option: <span class="hljs-string">'value'</span>
)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property6</span>
;
<span class="hljs-php-attribute">#[Assert\AttributeName(<span class="hljs-string">'value'</span>)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property7</span>
;
<span class="hljs-php-attribute">#[Assert\AttributeName(
<span class="hljs-string">'value'</span>,
option: <span class="hljs-string">'value'</span>
)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property8</span>
;
<span class="hljs-php-attribute">#[Route(<span class="hljs-string">'/blog/{page&lt;\d+&gt;}'</span>, name: <span class="hljs-string">'blog_list'</span>)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property9</span>
;
<span class="hljs-php-attribute">#[Assert\GreaterThanOrEqual(
value: <span class="hljs-number">18</span>,
)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property10</span>
;
<span class="hljs-php-attribute">#[ORM\CustomIdGenerator(class: <span class="hljs-string">'doctrine.uuid_generator'</span>)]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property11</span>
;
<span class="hljs-php-attribute">#[Assert\AtLeastOneOf([
<span class="hljs-keyword">new</span> Assert\Regex(<span class="hljs-string">'/#/'</span>),
<span class="hljs-keyword">new</span> Assert\Length(min: <span class="hljs-number">10</span>),
])]</span>
<span class="hljs-keyword">private</span>
<span class="hljs-variable">
<span class="hljs-variable-other-marker">$</span> property12</span>
;
}</code></pre>
</div>
</div>
56 changes: 56 additions & 0 deletions tests/fixtures/source/blocks/code-blocks/php-attributes.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.. code-block:: php-attributes
// src/SomePath/SomeClass.php
namespace App\SomePath;
use Symfony\Component\Validator\Constraints as Assert;
class SomeClass
{
#[AttributeName]
private $property1;
#[AttributeName()]
private $property2;
#[AttributeName('value')]
private $property3;
#[AttributeName('value', option: 'value')]
private $property4;
#[AttributeName(['value' => 'value'])]
private $property5;
#[AttributeName(
'value',
option: 'value'
)]
private $property6;
#[Assert\AttributeName('value')]
private $property7;
#[Assert\AttributeName(
'value',
option: 'value'
)]
private $property8;
#[Route('/blog/{page<\d+>}', name: 'blog_list')]
private $property9;
#[Assert\GreaterThanOrEqual(
value: 18,
)]
private $property10;
#[ORM\CustomIdGenerator(class: 'doctrine.uuid_generator')]
private $property11;
#[Assert\AtLeastOneOf([
new Assert\Regex('/#/'),
new Assert\Length(min: 10),
])]
private $property12;
}

0 comments on commit 81e707a

Please sign in to comment.