diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f55c69..331924b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,4 +28,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2.1.0] - 2023-06-13 - Set PHP minimum version in composer - Throws UnknownThemeException -- Added tests \ No newline at end of file +- Added tests + +## [3.0.0] - 2025-11-21 + +### Added +- Support for `
` pattern (in addition to ``) for better Markdown compatibility
+- Support for `class="language-*"` attribute on `` tag for language detection
+- Fluent interface for `showLineNumbers()` and `showActionPanel()` methods
+- `HighlighterFactory` class for creating highlighter instances based on language
+- `CodeBlockWrapper` class for separating presentation logic from highlighting
+- `LanguageNormalizer` class for normalizing language identifiers with aliases support
+- Custom exceptions: `InvalidLanguageException`, `InvalidThemeException`, `ThemeNotSetException`
+- PHP as default language for code blocks without specified language
+- Comprehensive test suite
+
+### Changed
+- **BREAKING**: Removed Singleton pattern from all highlighter classes (`HighlighterPHP`, `HighlighterXML`, `HighlighterBash`)
+- **BREAKING**: Made `HighlighterBase` an abstract class (cannot be instantiated directly)
+- **BREAKING**: Added `ext-dom` PHP extension requirement (previously optional with regex fallback)
+- Improved HTML attribute parsing using `DOMDocument` with regex fallback
+- Enhanced syntax highlighting logic in `HighlighterBase`
+- Improved XML/HTML highlighting: fixed line-by-line processing, proper attribute highlighting
+- Updated PHPDoc comments throughout the codebase
+
+### Fixed
+- Fixed issue with extra empty lines at the beginning and end of code blocks
+- Fixed line numbering
diff --git a/README.md b/README.md
index 4c6ce61..beb2372 100644
--- a/README.md
+++ b/README.md
@@ -3,11 +3,13 @@
PHPHighlight is a PHP syntax highlighting library that can be easily customized and extended.
## How it works
-The library parses the text, finds the \ tag, reads the attributes (data-lang, data-file, data-theme) and highlights the syntax of the code block.
+The library parses the text, finds the `` and `` tags, reads the attributes (data-lang, data-file, data-theme) and highlights the syntax of the code block.
+
+**Recommended:** Use `` pattern for better semantics and compatibility with Markdown output.
Supports style customization. Here are examples of styling:
-
+
## Requirements
PHP 8.1+
@@ -19,7 +21,7 @@ $ composer require demyanovs/php-highlight
```
## Usage
-See full example here [index.php](../master/examples/index.php)
+See full example in [examples/index.php](examples/index.php)
```php
+
<?php
abstract class AbstractClass
{
@@ -62,13 +64,12 @@ class ConcreteClass extends AbstractClass
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
-
+
';
-$highlighter = new Highlighter($text, ObsidianTheme::TITLE);
-// Configuration
-$highlighter->showLineNumbers(true);
-$highlighter->showActionPanel(true);
+$highlighter = (new Highlighter($text, ObsidianTheme::TITLE))
+ ->showLineNumbers(true)
+ ->showActionPanel(true);
echo $highlighter->parse();
```
@@ -78,19 +79,53 @@ $highlighter->showLineNumbers(true);
$highlighter->showActionPanel(true);
```
-You can set following attributes in \ tag
-\
-* lang - a language of the text. This affects how the parser will highlight the syntax.
-* file - show file name in action panel.
-* theme - allows to overwrite the global theme.
+You can set following attributes in `` or `` tags:
+```html
+
+// or
+
+```
+
+* `data-lang` or `class="language-*"` - a language of the text. This affects how the parser will highlight the syntax.
+* `data-file` - show file name in action panel.
+* `data-theme` - allows to overwrite the global theme.
+
+**Note:** `class="language-*"` on `` tag is automatically recognized (common in Markdown output).
### How to create a custom theme
-To create a custom theme you need to create an instance of Demyanovs\PHPHighlight\Themes\Theme class
+To create a custom theme you need to create an instance of `Demyanovs\PHPHighlight\Themes\Theme` class
and pass it to Highlighter as a third argument:
```php
-$defaultColorSchemaDto = new DefaultColorSchemaDto(...);
-$PHPColorSchemaDto = new PHPColorSchemaDto(...);
-$XMLColorSchemaDto = new XMLColorSchemaDto(...);
+use Demyanovs\PHPHighlight\Highlighter;
+use Demyanovs\PHPHighlight\Themes\Theme;
+use Demyanovs\PHPHighlight\Themes\Dto\DefaultColorSchemaDto;
+use Demyanovs\PHPHighlight\Themes\Dto\PHPColorSchemaDto;
+use Demyanovs\PHPHighlight\Themes\Dto\XMLColorSchemaDto;
+
+$defaultColorSchemaDto = new DefaultColorSchemaDto(
+ '#000000', // background
+ '#ffffff', // default text
+ '#888888', // comment
+ '#ff0000', // keyword
+ '#00ff00', // string
+ '#0000ff', // number
+ '#ffff00' // variable
+);
+
+$PHPColorSchemaDto = new PHPColorSchemaDto(
+ '#0000BB', // keyword
+ '#FF8000', // variable
+ '#fbc201', // function
+ '#007700', // string
+ '#DD0000' // comment
+);
+
+$XMLColorSchemaDto = new XMLColorSchemaDto(
+ '#008000', // tag
+ '#7D9029', // attribute
+ '#BA2121', // string
+ '#BC7A00' // comment
+);
$myTheme = new Theme(
'myThemeTitle',
@@ -124,5 +159,8 @@ Pull requests are welcome. For major changes, please open an issue first to disc
Please make sure to update tests as appropriate.
+## Changelog
+See [CHANGELOG.md](./CHANGELOG.md) for a list of changes and version history.
+
## License
[MIT](./LICENSE.md)
diff --git a/composer.json b/composer.json
index dc140b1..5d80088 100644
--- a/composer.json
+++ b/composer.json
@@ -17,7 +17,8 @@
}
],
"require": {
- "php": ">=8.1"
+ "php": ">=8.1",
+ "ext-dom": "*"
},
"autoload": {
"psr-4": {
@@ -31,13 +32,15 @@
},
"require-dev": {
"phpunit/phpunit": "^10.2",
- "squizlabs/php_codesniffer": "*",
+ "squizlabs/php_codesniffer": "^3.13",
"doctrine/coding-standard": "^12.0"
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true
- }
+ },
+ "sort-packages": true,
+ "prefer-stable": true
},
"scripts": {
"test": "./vendor/bin/phpunit",
diff --git a/examples/css/highlighter.css b/examples/css/highlighter.css
index 8e7c727..ac85c2c 100644
--- a/examples/css/highlighter.css
+++ b/examples/css/highlighter.css
@@ -54,3 +54,7 @@
.code-highlighter .line-number {
display: block;
}
+
+.code-block-wrapper .code-block {
+ display: block;
+}
diff --git a/examples/img/scr_01.png b/examples/img/scr_01.png
new file mode 100644
index 0000000..2bb0ada
Binary files /dev/null and b/examples/img/scr_01.png differ
diff --git a/examples/index.php b/examples/index.php
index 9ceb69b..61f6bc7 100644
--- a/examples/index.php
+++ b/examples/index.php
@@ -15,7 +15,7 @@
$text = '
PHP
-
+
<?php
abstract class AbstractClass
{
@@ -48,10 +48,10 @@ public function prefixName(string $name): string
$class = new ConcreteClass;
echo $class->prefixName("Pacman"), "\n";
echo $class->prefixName("Pacwoman"), "\n";
-
+
JavaScript
-
+
// Arrow functions let us omit the `function` keyword. Here `long_example`
// points to an anonymous function value.
const long_example = (input1, input2) => {
@@ -65,10 +65,10 @@ public function prefixName(string $name): string
long_example(2, 3); // Prints "Hello, World!" and returns 5.
short_example(2); // Returns 7.
-
+
Bash
-
+
#!/bin/bash
read -p "Enter number : " n
if test $n -ge 0
@@ -77,10 +77,10 @@ public function prefixName(string $name): string
else
echo "$n number is negative number."
fi
-
+
Go
-
+
package main
import "fmt"
@@ -104,9 +104,9 @@ public function prefixName(string $name): string
fmt.Scanln()
fmt.Println("done")
}
-
+
Xml
-
+
@@ -130,10 +130,10 @@ public function prefixName(string $name): string
-
+
HTML
-
+
Title
@@ -150,7 +150,7 @@ function $init() {return true;}
Mix all ingredients and knead thoroughly.