From 9bf816b084b77b9ff473316d682fc35bf21ceed7 Mon Sep 17 00:00:00 2001
From: oleibman <10341515+oleibman@users.noreply.github.com>
Date: Sun, 7 Jan 2024 12:27:24 -0800
Subject: [PATCH] Allow `rgb()` When Converting Html (#2512)
* Allow `rgb()` When Converting Html
Fix #2508. Program currently expects `#xxxxxx` to specify a color when used by the `bgcolor` html attribute or the `color` or `background-color` css attributes. This PR allows support for `rgb(red, green, blue)` as well.
* Update Change Log 2.0.0
---
docs/changes/2.x/2.0.0.md | 1 +
src/PhpWord/Shared/Html.php | 17 ++++++--
.../Writer/Word2007/Style/FontTest.php | 42 +++++++++++++++++++
3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/docs/changes/2.x/2.0.0.md b/docs/changes/2.x/2.0.0.md
index a8c3cd596e..c679317049 100644
--- a/docs/changes/2.x/2.0.0.md
+++ b/docs/changes/2.x/2.0.0.md
@@ -18,5 +18,6 @@
- Bump phpmd/phpmd from 2.14.1 to 2.15.0 by [@dependabot](https://github.com/dependabot) in [#2538](https://github.com/PHPOffice/PHPWord/pull/2538)
- Bump phpunit/phpunit from 9.6.14 to 9.6.15 by [@dependabot](https://github.com/dependabot) in [#2537](https://github.com/PHPOffice/PHPWord/pull/2537)
- Bump symfony/process from 5.4.28 to 5.4.34 by [@dependabot](https://github.com/dependabot) in [#2536](https://github.com/PHPOffice/PHPWord/pull/2536)
+- Allow rgb() when converting Html [@oleibman](https://github.com/oleibman) fixing [#2508](https://github.com/PHPOffice/PHPWord/issues/2508) in [#2512](https://github.com/PHPOffice/PHPWord/pull/2512)
### BC Breaks
diff --git a/src/PhpWord/Shared/Html.php b/src/PhpWord/Shared/Html.php
index 0a9b23979c..2022f7da09 100644
--- a/src/PhpWord/Shared/Html.php
+++ b/src/PhpWord/Shared/Html.php
@@ -37,6 +37,8 @@
*/
class Html
{
+ private const RGB_REGEXP = '/^\s*rgb\s*[(]\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*[)]\s*$/';
+
protected static $listIndex = 0;
protected static $xpath;
@@ -142,7 +144,7 @@ protected static function parseInlineStyle($node, $styles = [])
break;
case 'bgcolor':
// tables, rows, cells e.g.
- $styles['bgColor'] = trim($val, '# ');
+ $styles['bgColor'] = self::convertRgb($val);
break;
case 'valign':
@@ -720,11 +722,11 @@ protected static function parseStyleDeclarations(array $selectors, array $styles
break;
case 'color':
- $styles['color'] = trim($value, '#');
+ $styles['color'] = self::convertRgb($value);
break;
case 'background-color':
- $styles['bgColor'] = trim($value, '#');
+ $styles['bgColor'] = self::convertRgb($value);
break;
case 'line-height':
@@ -1170,4 +1172,13 @@ protected static function parseHorizRule($node, $element): void
// - line - that is a shape, has different behaviour
// - repeated text, e.g. underline "_", because of unpredictable line wrapping
}
+
+ private static function convertRgb(string $rgb): string
+ {
+ if (preg_match(self::RGB_REGEXP, $rgb, $matches) === 1) {
+ return sprintf('%02X%02X%02X', $matches[1], $matches[2], $matches[3]);
+ }
+
+ return trim($rgb, '# ');
+ }
}
diff --git a/tests/PhpWordTests/Writer/Word2007/Style/FontTest.php b/tests/PhpWordTests/Writer/Word2007/Style/FontTest.php
index 2c10b5ff2f..a8214ec35b 100644
--- a/tests/PhpWordTests/Writer/Word2007/Style/FontTest.php
+++ b/tests/PhpWordTests/Writer/Word2007/Style/FontTest.php
@@ -17,6 +17,8 @@
namespace PhpOffice\PhpWordTests\Writer\Word2007\Style;
+use PhpOffice\PhpWord\PhpWord;
+use PhpOffice\PhpWord\Shared\Html;
use PhpOffice\PhpWordTests\TestHelperDOCX;
/**
@@ -155,4 +157,44 @@ public function testPosition(): void
self::assertTrue($doc->elementExists($path));
self::assertEquals(-20, $doc->getElementAttribute($path, 'w:val'));
}
+
+ public static function testRgb(): void
+ {
+ $phpWord = new PhpWord();
+ $section = $phpWord->addSection(['pageNumberingStart' => 1]);
+ $html = implode(
+ "\n",
+ [
+ '',
+ '',
+ '',
+ 'This one is in color. | ',
+ 'This one too. | ',
+ '
',
+ '',
+ '
',
+ ]
+ );
+
+ Html::addHtml($section, $html, false, false);
+ $doc = TestHelperDOCX::getDocument($phpWord, 'Word2007');
+
+ $element = '/w:document/w:body/w:tbl/w:tr/w:tc/w:p/w:r';
+ $txtelem = $element . '/w:t';
+ $styelem = $element . '/w:rPr';
+ self::assertTrue($doc->elementExists($txtelem));
+ self::assertSame('This one is in color.', $doc->getElement($txtelem)->textContent);
+ self::assertTrue($doc->elementExists($styelem));
+ self::assertTrue($doc->elementExists($styelem . '/w:color'));
+ self::assertSame('A7D9C1', $doc->getElementAttribute($styelem . '/w:color', 'w:val'));
+
+ $element = '/w:document/w:body/w:tbl/w:tr/w:tc[2]/w:p/w:r';
+ $txtelem = $element . '/w:t';
+ $styelem = $element . '/w:rPr';
+ self::assertTrue($doc->elementExists($txtelem));
+ self::assertSame('This one too.', $doc->getElement($txtelem)->textContent);
+ self::assertTrue($doc->elementExists($styelem));
+ self::assertTrue($doc->elementExists($styelem . '/w:color'));
+ self::assertSame('A7D9C1', $doc->getElementAttribute($styelem . '/w:color', 'w:val'));
+ }
}