Fixed a few bugs

Added custom font-families
This commit is contained in:
Tim Otte 2020-03-03 10:19:05 +01:00
parent d5671f1c42
commit 8ce1f5f360
2 changed files with 34 additions and 16 deletions

View File

@ -1,7 +1,7 @@
<?php
// Learn more about this regex pattern: https://regexr.com/4un9u
define('HTML_REGEX_PATTERN', '/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/');
// Learn more about this regex pattern: https://regexr.com/4vi60
define('HTML_REGEX_PATTERN', '/<([A-Za-z]+)(?:\s([A-Za-z]+(?:\-[A-Za-z]+)?(?:=(?:".*?")|(?:[0-9]+))))*(?:(?:\s\/>)|(?:>(.*)<\/\1>))/');
class HtmlToOdtConverter {
@ -41,7 +41,7 @@ class HtmlToOdtConverter {
'<style:style style:name="supText" style:family="text"><style:text-properties style:text-position="super 58%" /></style:style>'
);
$odtText = self::replaceHtmlWithOdtTag(self::getDataFromHtml($htmlText), $customStyles);
$odtText = self::replaceHtmlWithOdtTag(self::getDataFromHtml($htmlText), $customStyles, $fontDeclarations);
foreach ($customStyles as $key => $value) {
array_push($automaticStyles, '<style:style style:name="customStyle' . $key . '" style:family="text">' . $value . '</style:style>');
@ -49,7 +49,8 @@ class HtmlToOdtConverter {
return array(
'automaticStyles' => $automaticStyles,
'content' => $odtText
'content' => $odtText,
'fonts' => $fontDeclarations
);
}
@ -58,8 +59,9 @@ class HtmlToOdtConverter {
* @param array $tags An array with html tags generated by the getDataFromHtml() function
* @param array $customStyles An array of style defenitions that should be included inside the odt file
*/
private static function replaceHtmlWithOdtTag($tags, &$customStyles) {
private static function replaceHtmlWithOdtTag($tags, &$customStyles, &$fontDeclarations) {
if ($customStyles == null) $customStyles = array();
if ($fontDeclarations == null) $fontDeclarations = array();
$odtResult = '';
@ -74,23 +76,23 @@ class HtmlToOdtConverter {
break;
case 'strong':
case 'b':
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="boldText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 'i':
case 'em':
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="italicText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 'u':
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="underlineText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 's':
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="strikethroughText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 'sub':
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="subText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 'sup':
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="supText">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
break;
case 'span':
if (isset($tag['attributes']['style'])) {
@ -98,7 +100,14 @@ class HtmlToOdtConverter {
foreach ($tag['attributes']['style'] as $styleName => $styleValue) {
switch ($styleName) {
case 'font-family':
$odtStyles .= '<style:text-properties style:font-name="Courier New" />';
$fontName = $styleValue;
if (strpos($fontName, ',') !== false) {
$fontName = explode(',', $fontName)[0];
}
if (!in_array($fontName, $fontDeclarations)) {
array_push($fontDeclarations, $fontName);
}
$odtStyles .= '<style:text-properties style:font-name="' . $fontName . '" />';
break;
case 'font-size':
if (preg_match('/([0-9]+)\s?(px|pt)/', $styleValue, $matches)) {
@ -117,14 +126,14 @@ class HtmlToOdtConverter {
}
}
if (strlen($odtStyles) > 0) {
$key = microtime();
$key = floatval(str_replace('.', '', microtime(true)))+rand(0, 10);
$customStyles[$key] = $odtStyles;
$odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '</text:span>';
$odtResult .= '<text:span text:style-name="customStyle' . $key . '">' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '</text:span>';
}
}
break;
default:
$odtResult .= self::replaceHtmlWithOdtTag($tag['children'], $customStyles);
$odtResult .= self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations);
break;
}
}
@ -171,7 +180,8 @@ class HtmlToOdtConverter {
$tempHtml = substr($tempHtml, $tagOffset);
}
// Extract the attribute data from the html tag
$explodedAttributes = strlen($matches[2][0]) > 0 ? explode(' ', $matches[2][0]) : array();
preg_match_all('/([0-9A-Za-z]+(?:="[0-9A-Za-z\:\-\s]*")?)+/', $matches[2][0], $explodedAttributes);
$explodedAttributes = array_filter($explodedAttributes[0]);
$attributes = array();
// Store each attribute with its name in the $attributes array
for ($i=0; $i<count($explodedAttributes); $i++) {

View File

@ -156,6 +156,14 @@ class Odf
}
}
$this->contentXml = str_replace('</office:automatic-styles>', $styles . '</office:automatic-styles>', $this->contentXml);
// Join the font declarations and add them to the content xml
$fonts = '';
foreach ($result['fonts'] as $font) {
if (strpos($this->contentXml, 'style:name="' . $font . '"') === false) {
$fonts .= '<style:font-face style:name="' . $font . '" svg:font-family="\'' . $font . '\'" />';
}
}
$this->contentXml = str_replace('</office:font-face-decls>', $fonts . '</office:font-face-decls>', $this->contentXml);
// Set the var to the converted odt value
$this->vars[$tag] = $result['content'];
}