diff --git a/htdocs/core/class/HtmlToOdtConverter.class.php b/htdocs/core/class/HtmlToOdtConverter.class.php
index 3df9d3cb3af..ff8e90ccfb0 100644
--- a/htdocs/core/class/HtmlToOdtConverter.class.php
+++ b/htdocs/core/class/HtmlToOdtConverter.class.php
@@ -1,7 +1,7 @@
)|(?:>(.*)<\/\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 {
''
);
- $odtText = self::replaceHtmlWithOdtTag(self::getDataFromHtml($htmlText), $customStyles);
+ $odtText = self::replaceHtmlWithOdtTag(self::getDataFromHtml($htmlText), $customStyles, $fontDeclarations);
foreach ($customStyles as $key => $value) {
array_push($automaticStyles, '' . $value . '');
@@ -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 .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
break;
case 'i':
case 'em':
- $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
break;
case 'u':
- $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
break;
case 's':
- $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
break;
case 'sub':
- $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
break;
case 'sup':
- $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
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 .= '';
+ $fontName = $styleValue;
+ if (strpos($fontName, ',') !== false) {
+ $fontName = explode(',', $fontName)[0];
+ }
+ if (!in_array($fontName, $fontDeclarations)) {
+ array_push($fontDeclarations, $fontName);
+ }
+ $odtStyles .= '';
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 .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles) : $tag['innerText']) . '';
+ $odtResult .= '' . ($tag['children'] != null ? self::replaceHtmlWithOdtTag($tag['children'], $customStyles, $fontDeclarations) : $tag['innerText']) . '';
}
}
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; $icontentXml = str_replace('', $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 .= '';
+ }
+ }
+ $this->contentXml = str_replace('', $fonts . '', $this->contentXml);
// Set the var to the converted odt value
$this->vars[$tag] = $result['content'];
}