|  | 
| 3 | 3 |  * Modified by Miles Johnson: http://milesj.me | 
| 4 | 4 |  * Rewritten by Tom Pavelec | 
| 5 | 5 |  * | 
| 6 |  | - * Supports PHP 5.3 - 7.4 | 
|  | 6 | + * Supports PHP 5.3 - 8.0 | 
| 7 | 7 |  */ | 
| 8 | 8 | (function (Prism) { | 
|  | 9 | +	var comment = /\/\*[\s\S]*?\*\/|\/\/.*|#(?!\[).*/; | 
|  | 10 | +	var constant = [ | 
|  | 11 | +		{ | 
|  | 12 | +			pattern: /\b(?:false|true)\b/i, | 
|  | 13 | +			alias: 'boolean' | 
|  | 14 | +		}, | 
|  | 15 | +		/\b[A-Z_][A-Z0-9_]*\b(?!\s*\()/, | 
|  | 16 | +		/\b(?:null)\b/i, | 
|  | 17 | +	]; | 
|  | 18 | +	var number = /\b0b[01]+\b|\b0x[\da-f]+\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)*|\B\.\d+)(?:e[+-]?\d+)?/i; | 
|  | 19 | +	var operator = /<?=>|\?\?=?|\.{3}|\??->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||<<|>>|[?~]|[/^|%*&<>.+-]=?/; | 
|  | 20 | +	var punctuation = /[{}\[\](),:;]/; | 
|  | 21 | + | 
| 9 | 22 | 	Prism.languages.php = { | 
| 10 | 23 | 		'delimiter': { | 
| 11 | 24 | 			pattern: /\?>$|^<\?(?:php(?=\s)|=)?/i, | 
| 12 | 25 | 			alias: 'important' | 
| 13 | 26 | 		}, | 
| 14 |  | -		'comment': [ | 
| 15 |  | -			/\/\*[\s\S]*?\*\/|\/\/.*|#.*/ | 
| 16 |  | -		], | 
|  | 27 | +		'comment': comment, | 
| 17 | 28 | 		'variable': /\$+(?:\w+\b|(?={))/i, | 
| 18 | 29 | 		'package': { | 
| 19 | 30 | 			pattern: /(namespace\s+|use\s+(?:function\s+)?)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, | 
|  | 
| 30 | 41 | 				lookbehind: true | 
| 31 | 42 | 			}, | 
| 32 | 43 | 			{ | 
| 33 |  | -				pattern: /([(,?]\s*)\b(?:bool|boolean|int|integer|float|string|object|array(?!\s*\()|mixed|self|static|callable|iterable)\b(?=\s*\$)/i, | 
|  | 44 | +				pattern: /([(,?]\s*)\b(?:bool|int|float|string|object|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b(?=\s*\$)/i, | 
| 34 | 45 | 				alias: 'type-hint', | 
| 35 | 46 | 				greedy: true, | 
| 36 | 47 | 				lookbehind: true | 
| 37 | 48 | 			}, | 
| 38 | 49 | 			{ | 
| 39 |  | -				pattern: /(\)\s*:\s*\?*\s*)\b(?:bool|boolean|int|integer|float|string|object|void|array(?!\s*\()|mixed|self|static|callable|iterable)\b/i, | 
|  | 50 | +				pattern: /([(,?]\s*[a-z0-9_|]\|\s*)(?:null|false)\b(?=\s*\$)/i, | 
|  | 51 | +				alias: 'type-hint', | 
|  | 52 | +				greedy: true, | 
|  | 53 | +				lookbehind: true | 
|  | 54 | +			}, | 
|  | 55 | +			{ | 
|  | 56 | +				pattern: /(\)\s*:\s*\??\s*)\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|self|static|callable|iterable|(?:null|false)(?=\s*\|))\b/i, | 
| 40 | 57 | 				alias: 'return-type', | 
| 41 | 58 | 				greedy: true, | 
| 42 | 59 | 				lookbehind: true | 
| 43 | 60 | 			}, | 
| 44 | 61 | 			{ | 
| 45 |  | -				pattern: /\b(?:bool|boolean|int|integer|float|string|object|void|array(?!\s*\()|mixed|iterable)\b/i, | 
|  | 62 | +				pattern: /(\)\s*:\s*\??\s*[a-z0-9_|]\|\s*)(?:null|false)\b/i, | 
|  | 63 | +				alias: 'return-type', | 
|  | 64 | +				greedy: true, | 
|  | 65 | +				lookbehind: true | 
|  | 66 | +			}, | 
|  | 67 | +			{ | 
|  | 68 | +				pattern: /\b(?:bool|int|float|string|object|void|array(?!\s*\()|mixed|iterable|(?:null|false)(?=\s*\|))\b/i, | 
| 46 | 69 | 				alias: 'type-declaration', | 
| 47 | 70 | 				greedy: true | 
| 48 | 71 | 			}, | 
|  | 72 | +			{ | 
|  | 73 | +				pattern: /(\|\s*)(?:null|false)\b/i, | 
|  | 74 | +				alias: 'type-declaration', | 
|  | 75 | +				greedy: true, | 
|  | 76 | +				lookbehind: true | 
|  | 77 | +			}, | 
| 49 | 78 | 			{ | 
| 50 | 79 | 				pattern: /\b(?:parent|self|static)(?=\s*::)/i, | 
| 51 | 80 | 				alias: 'static-context', | 
| 52 | 81 | 				greedy: true | 
| 53 | 82 | 			}, | 
| 54 | 83 | 			/\b(?:__halt_compiler|abstract|and|array|as|break|callable|case|catch|class|clone|const|continue|declare|default|die|do|echo|else|elseif|empty|enddeclare|endfor|endforeach|endif|endswitch|endwhile|eval|exit|extends|final|finally|for|foreach|function|global|goto|if|implements|include|include_once|instanceof|insteadof|interface|isset|list|namespace|match|new|or|parent|print|private|protected|public|require|require_once|return|self|static|switch|throw|trait|try|unset|use|var|while|xor|yield)\b/i | 
| 55 | 84 | 		], | 
|  | 85 | +		'argument-name': /\b[a-z_]\w*(?=\s*:(?!:))/i, | 
| 56 | 86 | 		'class-name': [ | 
| 57 | 87 | 			{ | 
| 58 |  | -				pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s+\()\b[a-z_]\w*(?!\\)\b/i, | 
|  | 88 | +				pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new(?!\s+self|\s+static))\s+|\bcatch\s*\()\b[a-z_]\w*(?!\\)\b/i, | 
|  | 89 | +				greedy: true, | 
|  | 90 | +				lookbehind: true | 
|  | 91 | +			}, | 
|  | 92 | +			{ | 
|  | 93 | +				pattern: /(\|\s*)\b[a-z_]\w*(?!\\)\b/i, | 
| 59 | 94 | 				greedy: true, | 
| 60 | 95 | 				lookbehind: true | 
| 61 | 96 | 			}, | 
| 62 | 97 | 			{ | 
| 63 |  | -				pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s+\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, | 
|  | 98 | +				pattern: /\b[a-z_]\w*(?!\\)\b(?=\s*\|)/i, | 
|  | 99 | +				greedy: true | 
|  | 100 | +			}, | 
|  | 101 | +			{ | 
|  | 102 | +				pattern: /(\|\s*)(?:\\?\b[a-z_]\w*)+\b/i, | 
|  | 103 | +				alias: 'class-name-fully-qualified', | 
|  | 104 | +				greedy: true, | 
|  | 105 | +				lookbehind: true, | 
|  | 106 | +				inside: { | 
|  | 107 | +					'punctuation': /\\/ | 
|  | 108 | +				} | 
|  | 109 | +			}, | 
|  | 110 | +			{ | 
|  | 111 | +				pattern: /(?:\\?\b[a-z_]\w*)+\b(?=\s*\|)/i, | 
|  | 112 | +				alias: 'class-name-fully-qualified', | 
|  | 113 | +				greedy: true, | 
|  | 114 | +				inside: { | 
|  | 115 | +					'punctuation': /\\/ | 
|  | 116 | +				} | 
|  | 117 | +			}, | 
|  | 118 | +			{ | 
|  | 119 | +				pattern: /(\b(?:extends|implements|instanceof|new(?!\s+self\b|\s+static\b))\s+|\bcatch\s*\()(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, | 
| 64 | 120 | 				alias: 'class-name-fully-qualified', | 
| 65 | 121 | 				greedy: true, | 
| 66 | 122 | 				lookbehind: true, | 
|  | 
| 110 | 166 | 				} | 
| 111 | 167 | 			}, | 
| 112 | 168 | 			{ | 
| 113 |  | -				pattern: /(\)\s*:\s*\?*\s*)\b[a-z_]\w*(?!\\)\b/i, | 
|  | 169 | +				pattern: /(\)\s*:\s*\??\s*)\b[a-z_]\w*(?!\\)\b/i, | 
| 114 | 170 | 				alias: 'return-type', | 
| 115 | 171 | 				greedy: true, | 
| 116 | 172 | 				lookbehind: true | 
| 117 | 173 | 			}, | 
| 118 | 174 | 			{ | 
| 119 |  | -				pattern: /(\)\s*:\s*\?*\s*)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, | 
|  | 175 | +				pattern: /(\)\s*:\s*\??\s*)(?:\\?\b[a-z_]\w*)+\b(?!\\)/i, | 
| 120 | 176 | 				alias: ['class-name-fully-qualified', 'return-type'], | 
| 121 | 177 | 				greedy: true, | 
| 122 | 178 | 				lookbehind: true, | 
|  | 
| 125 | 181 | 				} | 
| 126 | 182 | 			} | 
| 127 | 183 | 		], | 
| 128 |  | -		'constant': [ | 
| 129 |  | -			{ | 
| 130 |  | -				pattern: /\b(?:false|true)\b/i, | 
| 131 |  | -				alias: 'boolean' | 
| 132 |  | -			}, | 
| 133 |  | -			/\b[A-Z_][A-Z0-9_]*\b/, | 
| 134 |  | -			/\b(?:null)\b/i, | 
| 135 |  | -		], | 
|  | 184 | +		'constant': constant, | 
| 136 | 185 | 		'function': /\w+\s*(?=\()/, | 
| 137 | 186 | 		'property': { | 
| 138 | 187 | 			pattern: /(->)[\w]+/, | 
| 139 | 188 | 			lookbehind: true | 
| 140 | 189 | 		}, | 
| 141 |  | -		'number': /\b0b[01]+\b|\b0x[\da-f]+\b|(?:\b\d+(?:_\d+)*\.?(?:\d+(?:_\d+)*)*|\B\.\d+)(?:e[+-]?\d+)?/i, | 
| 142 |  | -		'operator': /<?=>|\?\?=?|\.{3}|->|[!=]=?=?|::|\*\*=?|--|\+\+|&&|\|\||[?~]|[/^|%*&<>.+-]=?/, | 
| 143 |  | -		'punctuation': /[{}\[\](),:;]/ | 
|  | 190 | +		'number': number, | 
|  | 191 | +		'operator': operator, | 
|  | 192 | +		'punctuation': punctuation | 
| 144 | 193 | 	}; | 
| 145 | 194 | 
 | 
| 146 | 195 | 	var string_interpolation = { | 
|  | 
| 149 | 198 | 		inside: Prism.languages.php | 
| 150 | 199 | 	}; | 
| 151 | 200 | 
 | 
| 152 |  | -	Prism.languages.insertBefore('php', 'variable', { | 
| 153 |  | -		'string': [ | 
| 154 |  | -			{ | 
| 155 |  | -				pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/, | 
| 156 |  | -				alias: 'nowdoc-string', | 
| 157 |  | -				greedy: true, | 
| 158 |  | -				inside: { | 
| 159 |  | -					'delimiter': { | 
| 160 |  | -						pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, | 
| 161 |  | -						alias: 'symbol', | 
| 162 |  | -						inside: { | 
| 163 |  | -							'punctuation': /^<<<'?|[';]$/ | 
| 164 |  | -						} | 
|  | 201 | +	var string = [ | 
|  | 202 | +		{ | 
|  | 203 | +			pattern: /<<<'([^']+)'[\r\n](?:.*[\r\n])*?\1;/, | 
|  | 204 | +			alias: 'nowdoc-string', | 
|  | 205 | +			greedy: true, | 
|  | 206 | +			inside: { | 
|  | 207 | +				'delimiter': { | 
|  | 208 | +					pattern: /^<<<'[^']+'|[a-z_]\w*;$/i, | 
|  | 209 | +					alias: 'symbol', | 
|  | 210 | +					inside: { | 
|  | 211 | +						'punctuation': /^<<<'?|[';]$/ | 
| 165 | 212 | 					} | 
| 166 | 213 | 				} | 
| 167 |  | -			}, | 
| 168 |  | -			{ | 
| 169 |  | -				pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i, | 
| 170 |  | -				alias: 'heredoc-string', | 
| 171 |  | -				greedy: true, | 
| 172 |  | -				inside: { | 
| 173 |  | -					'delimiter': { | 
| 174 |  | -						pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, | 
| 175 |  | -						alias: 'symbol', | 
| 176 |  | -						inside: { | 
| 177 |  | -							'punctuation': /^<<<"?|[";]$/ | 
| 178 |  | -						} | 
| 179 |  | -					}, | 
| 180 |  | -					'interpolation': string_interpolation // See below | 
| 181 |  | -				} | 
| 182 |  | -			}, | 
| 183 |  | -			{ | 
| 184 |  | -				pattern: /`(?:\\[\s\S]|[^\\`])*`/, | 
| 185 |  | -				alias: 'backtick-quoted-string', | 
| 186 |  | -				greedy: true | 
| 187 |  | -			}, | 
| 188 |  | -			{ | 
| 189 |  | -				pattern: /'(?:\\[\s\S]|[^\\'])*'/, | 
| 190 |  | -				alias: 'single-quoted-string', | 
| 191 |  | -				greedy: true | 
| 192 |  | -			}, | 
| 193 |  | -			{ | 
| 194 |  | -				pattern: /"(?:\\[\s\S]|[^\\"])*"/, | 
| 195 |  | -				alias: 'double-quoted-string', | 
| 196 |  | -				greedy: true, | 
| 197 |  | -				inside: { | 
| 198 |  | -					'interpolation': string_interpolation // See below | 
|  | 214 | +			} | 
|  | 215 | +		}, | 
|  | 216 | +		{ | 
|  | 217 | +			pattern: /<<<(?:"([^"]+)"[\r\n](?:.*[\r\n])*?\1;|([a-z_]\w*)[\r\n](?:.*[\r\n])*?\2;)/i, | 
|  | 218 | +			alias: 'heredoc-string', | 
|  | 219 | +			greedy: true, | 
|  | 220 | +			inside: { | 
|  | 221 | +				'delimiter': { | 
|  | 222 | +					pattern: /^<<<(?:"[^"]+"|[a-z_]\w*)|[a-z_]\w*;$/i, | 
|  | 223 | +					alias: 'symbol', | 
|  | 224 | +					inside: { | 
|  | 225 | +						'punctuation': /^<<<"?|[";]$/ | 
|  | 226 | +					} | 
|  | 227 | +				}, | 
|  | 228 | +				'interpolation': string_interpolation // See below | 
|  | 229 | +			} | 
|  | 230 | +		}, | 
|  | 231 | +		{ | 
|  | 232 | +			pattern: /`(?:\\[\s\S]|[^\\`])*`/, | 
|  | 233 | +			alias: 'backtick-quoted-string', | 
|  | 234 | +			greedy: true | 
|  | 235 | +		}, | 
|  | 236 | +		{ | 
|  | 237 | +			pattern: /'(?:\\[\s\S]|[^\\'])*'/, | 
|  | 238 | +			alias: 'single-quoted-string', | 
|  | 239 | +			greedy: true | 
|  | 240 | +		}, | 
|  | 241 | +		{ | 
|  | 242 | +			pattern: /"(?:\\[\s\S]|[^\\"])*"/, | 
|  | 243 | +			alias: 'double-quoted-string', | 
|  | 244 | +			greedy: true, | 
|  | 245 | +			inside: { | 
|  | 246 | +				'interpolation': string_interpolation // See below | 
|  | 247 | +			} | 
|  | 248 | +		} | 
|  | 249 | +	]; | 
|  | 250 | + | 
|  | 251 | +	Prism.languages.insertBefore('php', 'variable', { | 
|  | 252 | +		'string': string, | 
|  | 253 | +	}); | 
|  | 254 | + | 
|  | 255 | +	Prism.languages.insertBefore('php', 'variable', { | 
|  | 256 | +		'attribute': { | 
|  | 257 | +			pattern: /#\[(?:[^"'\/#]|\/(?![*/])|\/\/.*$|#(?!\[).*$|\/\*(?:[^*]|\*(?!\/))*\*\/|"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*')+\](?=\s*[a-z$#])/mi, | 
|  | 258 | +			greedy: true, | 
|  | 259 | +			inside: { | 
|  | 260 | +				'attribute-content': { | 
|  | 261 | +					pattern: /^(#\[)[\s\S]+(?=]$)/, | 
|  | 262 | +					lookbehind: true, | 
|  | 263 | +					// inside can appear subset of php | 
|  | 264 | +					inside: { | 
|  | 265 | +						'comment': comment, | 
|  | 266 | +						'string': string, | 
|  | 267 | +						'attribute-class-name': [ | 
|  | 268 | +							{ | 
|  | 269 | +								pattern: /([^:]|^)\b[a-z_]\w*(?!\\)\b/i, | 
|  | 270 | +								alias: 'class-name', | 
|  | 271 | +								greedy: true, | 
|  | 272 | +								lookbehind: true | 
|  | 273 | +							}, | 
|  | 274 | +							{ | 
|  | 275 | +								pattern: /([^:]|^)(?:\\?\b[a-z_]\w*)+/i, | 
|  | 276 | +								alias: [ | 
|  | 277 | +									'class-name', | 
|  | 278 | +									'class-name-fully-qualified' | 
|  | 279 | +								], | 
|  | 280 | +								greedy: true, | 
|  | 281 | +								lookbehind: true, | 
|  | 282 | +								inside: { | 
|  | 283 | +									'punctuation': /\\/ | 
|  | 284 | +								} | 
|  | 285 | +							} | 
|  | 286 | +						], | 
|  | 287 | +						'constant': constant, | 
|  | 288 | +						'number': number, | 
|  | 289 | +						'operator': operator, | 
|  | 290 | +						'punctuation': punctuation | 
|  | 291 | +					} | 
|  | 292 | +				}, | 
|  | 293 | +				'delimiter': { | 
|  | 294 | +					pattern: /^#\[|]$/, | 
|  | 295 | +					alias: 'punctuation' | 
| 199 | 296 | 				} | 
| 200 | 297 | 			} | 
| 201 |  | -		], | 
|  | 298 | +		}, | 
| 202 | 299 | 	}); | 
| 203 | 300 | 
 | 
| 204 | 301 | 	Prism.hooks.add('before-tokenize', function(env) { | 
| 205 | 302 | 		if (!/<\?/.test(env.code)) { | 
| 206 | 303 | 			return; | 
| 207 | 304 | 		} | 
| 208 | 305 | 
 | 
| 209 |  | -		var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#)(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig; | 
|  | 306 | +		var phpPattern = /<\?(?:[^"'/#]|\/(?![*/])|("|')(?:\\[\s\S]|(?!\1)[^\\])*\1|(?:\/\/|#(?!\[))(?:[^?\n\r]|\?(?!>))*(?=$|\?>|[\r\n])|#\[|\/\*[\s\S]*?(?:\*\/|$))*?(?:\?>|$)/ig; | 
| 210 | 307 | 		Prism.languages['markup-templating'].buildPlaceholders(env, 'php', phpPattern); | 
| 211 | 308 | 	}); | 
| 212 | 309 | 
 | 
|  | 
0 commit comments