Skip to content

Proper css inline border #1670 #2728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/changes/1.x/1.4.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Writer ODText: Support for images inside a textRun by [@Progi1984](https://github.com/Progi1984) fixing [#2240](https://github.com/PHPOffice/PHPWord/issues/2240) in [#2668](https://github.com/PHPOffice/PHPWord/pull/2668)
- Allow vAlign and vMerge on Style\Cell to be set to null by [@SpraxDev](https://github.com/SpraxDev) fixing [#2673](https://github.com/PHPOffice/PHPWord/issues/2673) in [#2676](https://github.com/PHPOffice/PHPWord/pull/2676)
- Reader HTML: Support for differents size units for table by [@Progi1984](https://github.com/Progi1984) fixing [#2384](https://github.com/PHPOffice/PHPWord/issues/2384), [#2701](https://github.com/PHPOffice/PHPWord/issues/2701) in [#2725](https://github.com/PHPOffice/PHPWord/pull/2725)
- Html addHTML : Support different order for inline style border by [@Azamat8405](https://github.com/Azamat8405) fixing [#1670](https://github.com/PHPOffice/PHPWord/issues/1670)
- Reader Word2007: Respect paragraph indent units by [@tugmaks](https://github.com/tugmaks) & [@Progi1984](https://github.com/Progi1984) fixing [#507](https://github.com/PHPOffice/PHPWord/issues/507) in [#2726](https://github.com/PHPOffice/PHPWord/pull/2726)
- Reader Word2007: Support Header elements within Title elements by [@SpraxDev](https://github.com/SpraxDev) fixing [#2616](https://github.com/PHPOffice/PHPWord/issues/2616), [#2426](https://github.com/PHPOffice/PHPWord/issues/2426) in [#2674](https://github.com/PHPOffice/PHPWord/pull/2674)
- Reader HTML: Support for inherit value for property line-height by [@Progi1984](https://github.com/Progi1984) fixing [#2683](https://github.com/PHPOffice/PHPWord/issues/2683) in [#2733](https://github.com/PHPOffice/PHPWord/pull/2733)
Expand Down
181 changes: 176 additions & 5 deletions src/PhpWord/Shared/Html.php
Original file line number Diff line number Diff line change
Expand Up @@ -898,9 +898,24 @@ protected static function parseStyleDeclarations(array $selectors, array $styles
case 'border-bottom':
case 'border-right':
case 'border-left':
// must have exact order [width color style], e.g. "1px #0011CC solid" or "2pt green solid"
$value = preg_replace('/ +/', ' ', trim($value));
$valueArr = explode(' ', strtolower($value));

$size = $color = $style = null;
// Word does not accept shortened hex colors e.g. #CCC, only full e.g. #CCCCCC
if (preg_match('/([0-9]+[^0-9]*)\s+(\#[a-fA-F0-9]+|[a-zA-Z]+)\s+([a-z]+)/', $value, $matches)) {
// we determine the order of color and style by checking value of the color.
$namedColors = self::mapNamedBorderColor();
foreach ($valueArr as $tmpValue) {
if (strpos($tmpValue, '#') === 0 || isset($namedColors[$tmpValue])) {
$color = trim($tmpValue, '#');
} elseif (preg_match('/[\-\d]+(px|pt|cm|mm|in|pc)/', $tmpValue) === 1) {
$size = Converter::cssToTwip($tmpValue);
} else {
$style = self::mapBorderStyle($tmpValue);
}
}

if ($size !== null && $color !== null && $style !== null) {
if (false !== strpos($property, '-')) {
$tmp = explode('-', $property);
$which = $tmp[1];
Expand All @@ -914,12 +929,11 @@ protected static function parseStyleDeclarations(array $selectors, array $styles
// Therefore we need to normalize converted twip value to cca 1/2 of value.
// This may be adjusted, if better ratio or formula found.
// BC change: up to ver. 0.17.0 was $size converted to points - Converter::cssToPoint($size)
$size = Converter::cssToTwip($matches[1]);
$size = (int) ($size / 2);
// valid variants may be e.g. borderSize, borderTopSize, borderLeftColor, etc ..
$styles["border{$which}Size"] = $size; // twips
$styles["border{$which}Color"] = trim($matches[2], '#');
$styles["border{$which}Style"] = self::mapBorderStyle($matches[3]);
$styles["border{$which}Color"] = $color;
$styles["border{$which}Style"] = $style;
}

break;
Expand Down Expand Up @@ -1068,12 +1082,169 @@ protected static function mapBorderStyle($cssBorderStyle)
case 'dashed':
case 'dotted':
case 'double':
case 'inset':
case 'outset':
return $cssBorderStyle;
default:
return 'single';
}
}

protected static function mapNamedBorderColor(): array
{
$colors = [];
$colors['aliceblue'] = '#f0f8ff';
$colors['antiquewhite'] = '#faebd7';
$colors['aqua'] = '#00ffff';
$colors['aquamarine'] = '#7fffd4';
$colors['azure'] = '#f0ffff';
$colors['beige'] = '#f5f5dc';
$colors['bisque'] = '#ffe4c4';
$colors['black'] = '#000000';
$colors['blanchedalmond'] = '#ffebcd';
$colors['blue'] = '#0000ff';
$colors['blueviolet'] = '#8a2be2';
$colors['brown'] = '#a52a2a';
$colors['burlywood'] = '#deb887';
$colors['cadetblue'] = '#5f9ea0';
$colors['chartreuse'] = '#7fff00';
$colors['chocolate'] = '#d2691e';
$colors['coral'] = '#ff7f50';
$colors['cornflowerblue'] = '#6495ed';
$colors['cornsilk'] = '#fff8dc';
$colors['crimson'] = '#dc143c';
$colors['cyan'] = '#00ffff';
$colors['darkblue'] = '#00008b';
$colors['darkcyan'] = '#008b8b';
$colors['darkgoldenrod'] = '#b8860b';
$colors['darkgray'] = '#a9a9a9';
$colors['darkgrey'] = '#a9a9a9';
$colors['darkgreen'] = '#006400';
$colors['darkkhaki'] = '#bdb76b';
$colors['darkmagenta'] = '#8b008b';
$colors['darkolivegreen'] = '#556b2f';
$colors['darkorange'] = '#ff8c00';
$colors['darkorchid'] = '#9932cc';
$colors['darkred'] = '#8b0000';
$colors['darksalmon'] = '#e9967a';
$colors['darkseagreen'] = '#8fbc8f';
$colors['darkslateblue'] = '#483d8b';
$colors['darkslategray'] = '#2f4f4f';
$colors['darkslategrey'] = '#2f4f4f';
$colors['darkturquoise'] = '#00ced1';
$colors['darkviolet'] = '#9400d3';
$colors['deeppink'] = '#ff1493';
$colors['deepskyblue'] = '#00bfff';
$colors['dimgray'] = '#696969';
$colors['dimgrey'] = '#696969';
$colors['dodgerblue'] = '#1e90ff';
$colors['firebrick'] = '#b22222';
$colors['floralwhite'] = '#fffaf0';
$colors['forestgreen'] = '#228b22';
$colors['fuchsia'] = '#ff00ff';
$colors['gainsboro'] = '#dcdcdc';
$colors['ghostwhite'] = '#f8f8ff';
$colors['gold'] = '#ffd700';
$colors['goldenrod'] = '#daa520';
$colors['gray'] = '#808080';
$colors['grey'] = '#808080';
$colors['green'] = '#008000';
$colors['greenyellow'] = '#adff2f';
$colors['honeydew'] = '#f0fff0';
$colors['hotpink'] = '#ff69b4';
$colors['indianred'] = '#cd5c5c';
$colors['indigo'] = '#4b0082';
$colors['ivory'] = '#fffff0';
$colors['khaki'] = '#f0e68c';
$colors['lavender'] = '#e6e6fa';
$colors['lavenderblush'] = '#fff0f5';
$colors['lawngreen'] = '#7cfc00';
$colors['lemonchiffon'] = '#fffacd';
$colors['lightblue'] = '#add8e6';
$colors['lightcoral'] = '#f08080';
$colors['lightcyan'] = '#e0ffff';
$colors['lightgoldenrodyellow'] = '#fafad2';
$colors['lightgray'] = '#d3d3d3';
$colors['lightgrey'] = '#d3d3d3';
$colors['lightgreen'] = '#90ee90';
$colors['lightpink'] = '#ffb6c1';
$colors['lightsalmon'] = '#ffa07a';
$colors['lightseagreen'] = '#20b2aa';
$colors['lightskyblue'] = '#87cefa';
$colors['lightslategray'] = '#778899';
$colors['lightslategrey'] = '#778899';
$colors['lightsteelblue'] = '#b0c4de';
$colors['lightyellow'] = '#ffffe0';
$colors['lime'] = '#00ff00';
$colors['limegreen'] = '#32cd32';
$colors['linen'] = '#faf0e6';
$colors['magenta'] = '#ff00ff';
$colors['maroon'] = '#800000';
$colors['mediumaquamarine'] = '#66cdaa';
$colors['mediumblue'] = '#0000cd';
$colors['mediumorchid'] = '#ba55d3';
$colors['mediumpurple'] = '#9370db';
$colors['mediumseagreen'] = '#3cb371';
$colors['mediumslateblue'] = '#7b68ee';
$colors['mediumspringgreen'] = '#00fa9a';
$colors['mediumturquoise'] = '#48d1cc';
$colors['mediumvioletred'] = '#c71585';
$colors['midnightblue'] = '#191970';
$colors['mintcream'] = '#f5fffa';
$colors['mistyrose'] = '#ffe4e1';
$colors['moccasin'] = '#ffe4b5';
$colors['navajowhite'] = '#ffdead';
$colors['navy'] = '#000080';
$colors['oldlace'] = '#fdf5e6';
$colors['olive'] = '#808000';
$colors['olivedrab'] = '#6b8e23';
$colors['orange'] = '#ffa500';
$colors['orangered'] = '#ff4500';
$colors['orchid'] = '#da70d6';
$colors['palegoldenrod'] = '#eee8aa';
$colors['palegreen'] = '#98fb98';
$colors['paleturquoise'] = '#afeeee';
$colors['palevioletred'] = '#db7093';
$colors['papayawhip'] = '#ffefd5';
$colors['peachpuff'] = '#ffdab9';
$colors['peru'] = '#cd853f';
$colors['pink'] = '#ffc0cb';
$colors['plum'] = '#dda0dd';
$colors['powderblue'] = '#b0e0e6';
$colors['purple'] = '#800080';
$colors['rebeccapurple'] = '#663399';
$colors['red'] = '#ff0000';
$colors['rosybrown'] = '#bc8f8f';
$colors['royalblue'] = '#4169e1';
$colors['saddlebrown'] = '#8b4513';
$colors['salmon'] = '#fa8072';
$colors['sandybrown'] = '#f4a460';
$colors['seagreen'] = '#2e8b57';
$colors['seashell'] = '#fff5ee';
$colors['sienna'] = '#a0522d';
$colors['silver'] = '#c0c0c0';
$colors['skyblue'] = '#87ceeb';
$colors['slateblue'] = '#6a5acd';
$colors['slategray'] = '#708090';
$colors['slategrey'] = '#708090';
$colors['snow'] = '#fffafa';
$colors['springgreen'] = '#00ff7f';
$colors['steelblue'] = '#4682b4';
$colors['tan'] = '#d2b48c';
$colors['teal'] = '#008080';
$colors['thistle'] = '#d8bfd8';
$colors['tomato'] = '#ff6347';
$colors['turquoise'] = '#40e0d0';
$colors['violet'] = '#ee82ee';
$colors['wheat'] = '#f5deb3';
$colors['white'] = '#ffffff';
$colors['whitesmoke'] = '#f5f5f5';
$colors['yellow'] = '#ffff00';
$colors['yellowgreen'] = '#9acd32';

return $colors;
}

protected static function mapBorderColor(&$styles, $cssBorderColor): void
{
$numColors = substr_count($cssBorderColor, '#');
Expand Down
1 change: 1 addition & 0 deletions src/PhpWord/Writer/Word2007/Style/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ private function writeBorder(XMLWriter $xmlWriter, TableStyle $style): void
$styleWriter = new MarginBorder($xmlWriter);
$styleWriter->setSizes($style->getBorderSize());
$styleWriter->setColors($style->getBorderColor());
$styleWriter->setStyles($style->getBorderStyle());
$styleWriter->write();

$xmlWriter->endElement(); // w:tblBorders
Expand Down