From 4e20e43e400c74e5e57ff011e3c6a647a4dfb018 Mon Sep 17 00:00:00 2001 From: Ventricule Date: Mon, 19 Feb 2018 23:07:10 +0100 Subject: [PATCH] update readme and embed html2document as submodule --- assets/html2opendocument/.gitignore | 8 - assets/html2opendocument/Base.php | 195 ----- assets/html2opendocument/LICENSE | 21 - assets/html2opendocument/README.md | 94 --- assets/html2opendocument/Spreadsheet.php | 694 ------------------ assets/html2opendocument/Text.php | 583 --------------- assets/html2opendocument/composer.json | 30 - .../default-template-with-replaces.odt | Bin 18589 -> 0 bytes assets/html2opendocument/default-template.ods | Bin 11004 -> 0 bytes assets/html2opendocument/default-template.odt | Bin 9627 -> 0 bytes assets/html2opendocument/demo2.php | 50 -- readme.md | 2 +- 12 files changed, 1 insertion(+), 1676 deletions(-) delete mode 100644 assets/html2opendocument/.gitignore delete mode 100644 assets/html2opendocument/Base.php delete mode 100644 assets/html2opendocument/LICENSE delete mode 100644 assets/html2opendocument/README.md delete mode 100644 assets/html2opendocument/Spreadsheet.php delete mode 100644 assets/html2opendocument/Text.php delete mode 100644 assets/html2opendocument/composer.json delete mode 100644 assets/html2opendocument/default-template-with-replaces.odt delete mode 100644 assets/html2opendocument/default-template.ods delete mode 100644 assets/html2opendocument/default-template.odt delete mode 100644 assets/html2opendocument/demo2.php diff --git a/assets/html2opendocument/.gitignore b/assets/html2opendocument/.gitignore deleted file mode 100644 index 72a07ce..0000000 --- a/assets/html2opendocument/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -composer.phar -composer.lock -/vendor/ -.idea - -# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file -# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file -# composer.lock diff --git a/assets/html2opendocument/Base.php b/assets/html2opendocument/Base.php deleted file mode 100644 index 35ed61c..0000000 --- a/assets/html2opendocument/Base.php +++ /dev/null @@ -1,195 +0,0 @@ - - * @license https://opensource.org/licenses/MIT - */ - -namespace CatoTH\HTML2OpenDocument; - -abstract class Base -{ - const NS_OFFICE = 'urn:oasis:names:tc:opendocument:xmlns:office:1.0'; - const NS_TEXT = 'urn:oasis:names:tc:opendocument:xmlns:text:1.0'; - const NS_FO = 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0'; - const NS_STYLE = 'urn:oasis:names:tc:opendocument:xmlns:style:1.0'; - const NS_TABLE = 'urn:oasis:names:tc:opendocument:xmlns:table:1.0'; - const NS_CALCTEXT = 'urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0'; - const NS_XLINK = 'http://www.w3.org/1999/xlink'; - - - /** @var \DOMDocument */ - protected $doc = null; - - /** @var bool */ - protected $DEBUG = false; - protected $trustHtml = false; - - /** @var string */ - protected $tmpPath = '/tmp/'; - - /** @var \ZipArchive */ - private $zip; - - /** @var @string */ - private $tmpZipFile; - - - /** - * @param string $templateFile - * @param array $options - * @throws \Exception - */ - public function __construct($templateFile, $options = []) - { - $template = file_get_contents($templateFile); - if (isset($options['tmpPath']) && $options['tmpPath'] != '') { - $this->tmpPath = $options['tmpPath']; - } - if (isset($options['trustHtml'])) { - $this->trustHtml = ($options['trustHtml'] == true); - } - - if(!file_exists($this->tmpPath)){ - mkdir($this->tmpPath); - } - - $this->tmpZipFile = $this->tmpPath . uniqid('zip-'); - file_put_contents($this->tmpZipFile, $template); - - $this->zip = new \ZipArchive(); - if ($this->zip->open($this->tmpZipFile) !== true) { - throw new \Exception("cannot open <$this->tmpZipFile>\n"); - } - - $content = $this->zip->getFromName('content.xml'); - - $this->doc = new \DOMDocument(); - $this->doc->loadXML($content); - - } - - /** - * @return string - */ - public function finishAndGetDocument() - { - $content = $this->create(); - - $this->zip->deleteName('content.xml'); - $this->zip->addFromString('content.xml', $content); - $this->zip->close(); - - $content = file_get_contents($this->tmpZipFile); - unlink($this->tmpZipFile); - return $content; - } - - /** - * @return string - */ - abstract function create(); - - /** - * @param string $html - * @param array $config - * @return string - */ - protected function purifyHTML($html, $config) - { - $configInstance = \HTMLPurifier_Config::create($config); - $configInstance->autoFinalize = false; - $purifier = \HTMLPurifier::instance($configInstance); - $purifier->config->set('Cache.SerializerPath', $this->tmpPath); - - return $purifier->purify($html); - return $html; - } - - /** - * @param string $html - * @return \DOMNode - */ - public function html2DOM($html) - { - if (!$this->trustHtml) { - $html = $this->purifyHTML( - $html, - [ - 'HTML.Doctype' => 'HTML 4.01 Transitional', - 'HTML.Trusted' => true, - 'CSS.Trusted' => true, - ] - ); - } - - $src_doc = new \DOMDocument(); - $src_doc->loadHTML(' - -' . $html . ""); - $bodies = $src_doc->getElementsByTagName('body'); - - return $bodies->item(0); - } - - /*** - * @param bool $debug - */ - public function setDebug($debug) - { - $this->DEBUG = $debug; - } - - /** - */ - public function debugOutput() - { - $this->doc->preserveWhiteSpace = false; - $this->doc->formatOutput = true; - echo htmlentities($this->doc->saveXML(), ENT_COMPAT, 'UTF-8'); - die(); - } - - /** - * @param string $styleName - * @param string $family - * @param string $element - * @param string[] $attributes - */ - protected function appendStyleNode($styleName, $family, $element, $attributes) - { - $node = $this->doc->createElementNS(static::NS_STYLE, 'style'); - $node->setAttribute('style:name', $styleName); - $node->setAttribute('style:family', $family); - - $style = $this->doc->createElementNS(static::NS_STYLE, $element); - foreach ($attributes as $att_name => $att_val) { - $style->setAttribute($att_name, $att_val); - } - $node->appendChild($style); - - foreach ($this->doc->getElementsByTagNameNS(static::NS_OFFICE, 'automatic-styles') as $element) { - /** @var \DOMElement $element */ - $element->appendChild($node); - } - } - - /** - * @param string $styleName - * @param array $attributes - */ - protected function appendTextStyleNode($styleName, $attributes) - { - $this->appendStyleNode($styleName, 'text', 'text-properties', $attributes); - } - - /** - * @param string $styleName - * @param array $attributes - */ - protected function appendParagraphStyleNode($styleName, $attributes) - { - $this->appendStyleNode($styleName, 'paragraph', 'paragraph-properties', $attributes); - } -} diff --git a/assets/html2opendocument/LICENSE b/assets/html2opendocument/LICENSE deleted file mode 100644 index 5c53027..0000000 --- a/assets/html2opendocument/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016 Tobias Hößl - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/assets/html2opendocument/README.md b/assets/html2opendocument/README.md deleted file mode 100644 index 4112a37..0000000 --- a/assets/html2opendocument/README.md +++ /dev/null @@ -1,94 +0,0 @@ -This is a simple PHP-library to create create OpenDocument Text- and Spreadsheet-files (ODT / ODS) from HTML-formatted text. - -It does not support formulae / calculations in spreadsheets. The focus lies on formatted text. - - -## Example Scripts - -A demo script for the OpenDocument Text converter using the default template: - -```php -require_once(__DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'); - -$html = '

This is a demo for the converter.

-

The converter supports the following styles:

- -
You can also use BLOCKQUOTE, though it lacks specific styling for now
'; - -$html2 = '

You might be interested
in the fact that this converter
-also supports
line numbering
for selected paragraphs

-

Dummy Line
Dummy Line
Dummy Line
-Dummy Line
Dummy Line

'; - -$odt = new \CatoTH\HTML2OpenDocument\Text(); -$odt->addHtmlTextBlock('

Test Page

'); -$odt->addHtmlTextBlock($html, false); -$odt->addHtmlTextBlock('

Line Numbering

'); -$odt->addHtmlTextBlock($html2, true); -$odt->finishAndOutputOdt('demo.odt'); -``` - - -A demo script for the OpenDocument Spreadsheet converter using the default template: - -```php -use CatoTH\HTML2OpenDocument\Spreadsheet; -require_once(__DIR__ . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'); - -$ods = new \CatoTH\HTML2OpenDocument\Spreadsheet(); - -// Plain text -$ods->setCell(0, 0, Spreadsheet::TYPE_TEXT, 'Plain text with native formatting'); -$ods->setCellStyle(0, 0, [], ['fo:font-weight' => 'bold']); - -// Print a number as an actual number, just a little bit bigger -$ods->setCell(1, 0, Spreadsheet::TYPE_NUMBER, 23); -$ods->setCellStyle(1, 0, [], [ - 'fo:font-size' => '16pt', - 'fo:font-weight' => 'bold', -]); -$ods->setMinRowHeight(1, 1.5); - -// Print a number as text -$ods->setCell(2, 0, Spreadsheet::TYPE_TEXT, '42'); - -// Draw a border around two of the cells -$ods->drawBorder(1, 0, 2, 0, 1); - - -// Now we use HTML, and we need a bit more space for that -$html = '

The converter supports the following styles:

- -
You can also use BLOCKQUOTE, though it lacks specific styling for now
'; - -$ods->setMinRowHeight(3, 10); -$ods->setColumnWidth(1, 20); -$ods->setCell(3, 1, Spreadsheet::TYPE_HTML, $html); - - -$ods->finishAndOutputOds('demo.ods'); -``` - - - -## License - -This library is licensed under the [MIT license](http://opensource.org/licenses/MIT) \ No newline at end of file diff --git a/assets/html2opendocument/Spreadsheet.php b/assets/html2opendocument/Spreadsheet.php deleted file mode 100644 index 5f6559d..0000000 --- a/assets/html2opendocument/Spreadsheet.php +++ /dev/null @@ -1,694 +0,0 @@ - - * @license https://opensource.org/licenses/MIT - */ - -namespace CatoTH\HTML2OpenDocument; - -class Spreadsheet extends Base -{ - const TYPE_TEXT = 0; - const TYPE_NUMBER = 1; - const TYPE_HTML = 2; - const TYPE_LINK = 3; - - const FORMAT_LINEBREAK = 0; - const FORMAT_BOLD = 1; - const FORMAT_ITALIC = 2; - const FORMAT_UNDERLINED = 3; - const FORMAT_STRIKE = 4; - const FORMAT_INS = 5; - const FORMAT_DEL = 6; - const FORMAT_LINK = 7; - const FORMAT_INDENTED = 8; - const FORMAT_SUP = 9; - const FORMAT_SUB = 10; - - public static $FORMAT_NAMES = [ - 0 => 'linebreak', - 1 => 'bold', - 2 => 'italic', - 3 => 'underlined', - 4 => 'strike', - 5 => 'ins', - 6 => 'del', - 7 => 'link', - 8 => 'indented', - 9 => 'sup', - 10 => 'sub', - ]; - - /** @var \DOMDocument */ - protected $doc = null; - - /** @var \DOMElement */ - protected $domTable; - - protected $matrix = []; - protected $matrixRows = 0; - protected $matrixCols = 0; - protected $matrixColWidths = []; - protected $matrixRowHeights = []; - - protected $rowNodes = []; - protected $cellNodeMatrix = []; - protected $cellStylesMatrix = []; - - protected $classCache = []; - - /** - * @param array $options - * @throws \Exception - */ - public function __construct($options = []) - { - if (isset($options['templateFile']) && $options['templateFile'] != '') { - $templateFile = $options['templateFile']; - } else { - $templateFile = __DIR__ . DIRECTORY_SEPARATOR . 'default-template.ods'; - } - parent::__construct($templateFile, $options); - } - - /** - * @param string $filename - */ - public function finishAndOutputOds($filename = '') - { - header('Content-Type: application/vnd.oasis.opendocument.spreadsheet'); - if ($filename != '') { - header('Content-disposition: attachment;filename="' . addslashes($filename) . '"'); - } - - echo $this->finishAndGetDocument(); - - die(); - } - - /** - * @param string $styleName - * @param array $cellAttributes - * @param array $textAttributes - */ - protected function appendCellStyleNode($styleName, $cellAttributes, $textAttributes) - { - $node = $this->doc->createElementNS(static::NS_STYLE, "style"); - $node->setAttribute("style:name", $styleName); - $node->setAttribute("style:family", 'table-cell'); - $node->setAttribute("style:parent-style-name", "Default"); - - if (count($cellAttributes) > 0) { - $style = $this->doc->createElementNS(static::NS_STYLE, 'table-cell-properties'); - foreach ($cellAttributes as $att_name => $att_val) { - $style->setAttribute($att_name, $att_val); - } - $node->appendChild($style); - } - if (count($textAttributes) > 0) { - $style = $this->doc->createElementNS(static::NS_STYLE, 'text-properties'); - foreach ($textAttributes as $att_name => $att_val) { - $style->setAttribute($att_name, $att_val); - } - $node->appendChild($style); - } - - foreach ($this->doc->getElementsByTagNameNS(static::NS_OFFICE, 'automatic-styles') as $element) { - /** @var \DOMElement $element */ - $element->appendChild($node); - } - } - - - /** - * @param string $styleName - * @param array $attributes - */ - protected function appendColStyleNode($styleName, $attributes) - { - $this->appendStyleNode($styleName, 'table-column', 'table-column-properties', $attributes); - } - - /** - * @param string $styleName - * @param array $attributes - */ - protected function appendRowStyleNode($styleName, $attributes) - { - $this->appendStyleNode($styleName, 'table-row', 'table-row-properties', $attributes); - } - - /** - * @param int $row - */ - protected function initRow($row) - { - if (!isset($this->matrix[$row])) { - $this->matrix[$row] = []; - } - if ($row > $this->matrixRows) { - $this->matrixRows = $row; - } - } - - /** - * @param int $row - * @param string $col - * @param int $contentType - * @param string $content - * @param null|string $cssClass - * @param null|string $styles - */ - public function setCell($row, $col, $contentType, $content, $cssClass = null, $styles = null) - { - $this->initRow($row); - if ($col > $this->matrixCols) { - $this->matrixCols = $col; - } - $this->matrix[$row][$col] = [ - 'type' => $contentType, - 'content' => $content, - 'class' => $cssClass, - 'styles' => $styles, - ]; - } - - /** - * @param int $col - * @param float $widthInCm - */ - public function setColumnWidth($col, $widthInCm) - { - $this->matrixColWidths[$col] = $widthInCm; - } - - /** - * @param int $row - * @param float $minHeightInCm - */ - public function setMinRowHeight($row, $minHeightInCm) - { - $this->initRow($row); - $rowHeight = (isset($this->matrixRowHeights[$row]) ? $this->matrixRowHeights[$row] : 1); - if ($minHeightInCm > $rowHeight) { - $rowHeight = $minHeightInCm; - } - $this->matrixRowHeights[$row] = $rowHeight; - } - - /** - * @return \DOMElement - * @throws \Exception - */ - protected function getCleanDomTable() - { - $domTables = $this->doc->getElementsByTagNameNS(static::NS_TABLE, 'table'); - if ($domTables->length != 1) { - throw new \Exception('Could not parse ODS template'); - } - - $this->domTable = $domTables->item(0); - - $children = $this->domTable->childNodes; - for ($i = $children->length - 1; $i >= 0; $i--) { - $this->domTable->removeChild($children->item($i)); - } - return $this->domTable; - } - - - /** - */ - protected function setColStyles() - { - for ($col = 0; $col <= $this->matrixCols; $col++) { - $element = $this->doc->createElementNS(static::NS_TABLE, 'table-column'); - if (isset($this->matrixColWidths[$col])) { - $element->setAttribute('table:style-name', 'Antragsgruen_col_' . $col); - $this->appendColStyleNode('Antragsgruen_col_' . $col, [ - 'style:column-width' => $this->matrixColWidths[$col] . 'cm', - ]); - } - $this->domTable->appendChild($element); - } - } - - - /** - */ - protected function setCellContent() - { - for ($row = 0; $row <= $this->matrixRows; $row++) { - $this->cellNodeMatrix[$row] = []; - $currentRow = $this->doc->createElementNS(static::NS_TABLE, 'table-row'); - for ($col = 0; $col <= $this->matrixCols; $col++) { - $this->cellNodeMatrix[$row][$col] = []; - $currentCell = $this->doc->createElementNS(static::NS_TABLE, 'table-cell'); - if (isset($this->matrix[$row][$col])) { - $cell = $this->matrix[$row][$col]; - switch ($cell["type"]) { - case static::TYPE_TEXT: - $elementP = $this->doc->createElementNS(static::NS_TEXT, 'p'); - $elementP->textContent = $cell['content']; - $currentCell->appendChild($elementP); - break; - case static::TYPE_NUMBER: - $elementP = $this->doc->createElementNS(static::NS_TEXT, 'p'); - $elementP->textContent = $cell['content']; - $currentCell->appendChild($elementP); - $currentCell->setAttribute('calcext:value-type', 'float'); - $currentCell->setAttribute('office:value-type', 'float'); - $currentCell->setAttribute('office:value', (string)$cell['content']); - break; - case static::TYPE_LINK: - $elementP = $this->doc->createElementNS(static::NS_TEXT, 'p'); - $elementA = $this->doc->createElementNS(static::NS_TEXT, 'a'); - $elementA->setAttributeNS(static::NS_XLINK, 'xlink:href', $cell['content']['href']); - $textNode = $this->doc->createTextNode($cell['content']['text']); - $elementA->appendChild($textNode); - $elementP->appendChild($elementA); - $currentCell->appendChild($elementP); - break; - case static::TYPE_HTML: - $nodes = $this->html2OdsNodes($cell['content']); - foreach ($nodes as $node) { - $currentCell->appendChild($node); - } - - //$this->setMinRowHeight($row, count($ps)); - $styles = $cell['styles']; - if (isset($styles['fo:wrap-option']) && $styles['fo:wrap-option'] == 'no-wrap') { - $wrap = 'no-wrap'; - $height = 1; - } else { - $wrap = 'wrap'; - $width = (isset($this->matrixColWidths[$col]) ? $this->matrixColWidths[$col] : 2); - $height = (mb_strlen(strip_tags($this->matrix[$row][$col]['content'])) / ($width * 6)); - } - $this->setCellStyle($row, $col, [ - 'fo:wrap-option' => $wrap, - ], [ - 'fo:hyphenate' => 'true', - ]); - $this->setMinRowHeight($row, $height); - break; - } - } - $currentRow->appendChild($currentCell); - $this->cellNodeMatrix[$row][$col] = $currentCell; - } - $this->domTable->appendChild($currentRow); - $this->rowNodes[$row] = $currentRow; - } - } - - /** - * @param int $row - * @param int $col - * @param null|array $cellAttributes - * @param null|array $textAttributes - */ - public function setCellStyle($row, $col, $cellAttributes, $textAttributes) - { - if (!isset($this->cellStylesMatrix[$row])) { - $this->cellStylesMatrix[$row] = []; - } - if (!isset($this->cellStylesMatrix[$row][$col])) { - $this->cellStylesMatrix[$row][$col] = ['cell' => [], 'text' => []]; - } - if (is_array($cellAttributes)) { - foreach ($cellAttributes as $key => $val) { - $this->cellStylesMatrix[$row][$col]['cell'][$key] = $val; - } - } - if (is_array($textAttributes)) { - foreach ($textAttributes as $key => $val) { - $this->cellStylesMatrix[$row][$col]['text'][$key] = $val; - } - } - } - - /** - */ - public function setCellStyles() - { - for ($row = 0; $row <= $this->matrixRows; $row++) { - for ($col = 0; $col <= $this->matrixCols; $col++) { - if (isset($this->cellStylesMatrix[$row]) && isset($this->cellStylesMatrix[$row][$col])) { - $cell = $this->cellStylesMatrix[$row][$col]; - } else { - $cell = ['cell' => [], 'text' => []]; - } - - $styleId = 'Antragsgruen_cell_' . $row . '_' . $col; - $cellStyles = array_merge([ - 'style:vertical-align' => 'top' - ], $cell['cell']); - $this->appendCellStyleNode($styleId, $cellStyles, $cell['text']); - /** @var \DOMElement $currentCell */ - $currentCell = $this->cellNodeMatrix[$row][$col]; - $currentCell->setAttribute('table:style-name', $styleId); - } - } - /* - foreach ($this->cellStylesMatrix as $rowNr => $row) { - foreach ($row as $colNr => $cell) { - } - } - */ - } - - /** - */ - public function setRowStyles() - { - foreach ($this->matrixRowHeights as $row => $height) { - $styleName = 'Antragsgruen_row_' . $row; - $this->appendRowStyleNode($styleName, [ - 'style:row-height' => ($height * 0.45) . 'cm', - ]); - - /** @var \DOMElement $node */ - $node = $this->rowNodes[$row]; - $node->setAttribute('table:style-name', $styleName); - } - } - - /** - * @param int $fromRow - * @param int $fromCol - * @param int $toRow - * @param int $toCol - * @param float $width - */ - public function drawBorder($fromRow, $fromCol, $toRow, $toCol, $width) - { - for ($i = $fromRow; $i <= $toRow; $i++) { - $this->setCellStyle($i, $fromCol, [ - 'fo:border-left' => $width . 'pt solid #000000', - ], []); - $this->setCellStyle($i, $toCol, [ - 'fo:border-right' => $width . 'pt solid #000000', - ], []); - } - - for ($i = $fromCol; $i <= $toCol; $i++) { - $this->setCellStyle($fromRow, $i, [ - 'fo:border-top' => $width . 'pt solid #000000', - ], []); - $this->setCellStyle($toRow, $i, [ - 'fo:border-bottom' => $width . 'pt solid #000000', - ], []); - } - } - - /** - * @param \DOMElement $node - * @param array $currentFormats - * @return array - */ - protected function node2Formatting(\DOMElement $node, $currentFormats) - { - switch ($node->nodeName) { - case 'b': - case 'strong': - $currentFormats[] = static::FORMAT_BOLD; - break; - case 'i': - case 'em': - $currentFormats[] = static::FORMAT_ITALIC; - break; - case 's': - $currentFormats[] = static::FORMAT_STRIKE; - break; - case 'u': - $currentFormats[] = static::FORMAT_UNDERLINED; - break; - case 'sub': - $currentFormats[] = static::FORMAT_SUB; - break; - case 'sup': - $currentFormats[] = static::FORMAT_SUP; - break; - case 'br': - break; - case 'p': - case 'div': - case 'blockquote': - if ($node->hasAttribute('class')) { - $classes = explode(' ', $node->getAttribute('class')); - if (in_array('underline', $classes)) { - $currentFormats[] = static::FORMAT_UNDERLINED; - } - if (in_array('strike', $classes)) { - $currentFormats[] = static::FORMAT_STRIKE; - } - if (in_array('ins', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('inserted', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('del', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - if (in_array('deleted', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - } - break; - case 'ul': - case 'ol': - if ($node->hasAttribute('class')) { - $classes = explode(' ', $node->getAttribute('class')); - $currentFormats[] = static::FORMAT_INDENTED; - if (in_array('ins', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('inserted', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('del', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - if (in_array('deleted', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - } - break; - case 'li': - break; - case 'del': - $currentFormats[] = static::FORMAT_DEL; - break; - case 'ins': - $currentFormats[] = static::FORMAT_INS; - break; - case 'h1': - case 'h2': - case 'h3': - case 'h4': - case 'h5': - case 'h6': - $currentFormats[] = static::FORMAT_BOLD; - break; - case 'a': - $currentFormats[] = static::FORMAT_LINK; - try { - $attr = $node->getAttribute('href'); - if ($attr) { - $currentFormats['href'] = $attr; - } - } catch (\Exception $e) { - } - break; - case 'span': - default: - if ($node->hasAttribute('class')) { - $classes = explode(' ', $node->getAttribute('class')); - if (in_array('underline', $classes)) { - $currentFormats[] = static::FORMAT_UNDERLINED; - } - if (in_array('strike', $classes)) { - $currentFormats[] = static::FORMAT_STRIKE; - } - if (in_array('ins', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('inserted', $classes)) { - $currentFormats[] = static::FORMAT_INS; - } - if (in_array('del', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - if (in_array('deleted', $classes)) { - $currentFormats[] = static::FORMAT_DEL; - } - if (in_array('superscript', $classes)) { - $currentFormats[] = static::FORMAT_SUP; - } - if (in_array('subscript', $classes)) { - $currentFormats[] = static::FORMAT_SUB; - } - } - break; - } - return $currentFormats; - } - - /** - * @param \DOMNode $node - * @param array $currentFormats - * @return array - */ - protected function tokenizeFlattenHtml(\DOMNode $node, $currentFormats) - { - $return = []; - foreach ($node->childNodes as $child) { - switch ($child->nodeType) { - case XML_ELEMENT_NODE: - /** @var \DOMElement $child */ - $formattings = $this->node2Formatting($child, $currentFormats); - $children = $this->tokenizeFlattenHtml($child, $formattings); - $return = array_merge($return, $children); - if (in_array($child->nodeName, ['br', 'div', 'p', 'li', 'blockquote'])) { - $return[] = [ - 'text' => '', - 'formattings' => [static::FORMAT_LINEBREAK], - ]; - } - if (in_array($child->nodeName, ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])) { - $return[] = [ - 'text' => '', - 'formattings' => [static::FORMAT_LINEBREAK, static::FORMAT_BOLD], - ]; - } - break; - case XML_TEXT_NODE: - /** @var \DOMText $child */ - $return[] = [ - 'text' => $child->data, - 'formattings' => $currentFormats, - ]; - break; - default: - } - } - - return $return; - } - - /** - * @param array $formats - * @return string - */ - protected function getClassByFormats($formats) - { - sort($formats); - $key = implode('_', $formats); - if (!isset($this->classCache[$key])) { - $name = 'Antragsgruen'; - $styles = []; - foreach ($formats as $format) { - if (!isset(static::$FORMAT_NAMES[$format])) { - continue; - } - $name .= '_' . static::$FORMAT_NAMES[$format]; - switch ($format) { - case static::FORMAT_INS: - $styles['fo:color'] = '#00ff00'; - $styles['style:text-underline-style'] = 'solid'; - $styles['style:text-underline-width'] = 'auto'; - $styles['style:text-underline-color'] = 'font-color'; - break; - case static::FORMAT_DEL: - $styles['fo:color'] = '#ff0000'; - $styles['style:text-line-through-type'] = 'single'; - break; - case static::FORMAT_BOLD: - $styles['fo:font-weight'] = 'bold'; - $styles['style:font-weight-asian'] = 'bold'; - $styles['style:font-weight-complex'] = 'bold'; - break; - case static::FORMAT_UNDERLINED: - $styles['style:text-underline-width'] = 'auto'; - $styles['style:text-underline-color'] = 'font-color'; - $styles['style:text-underline-style'] = 'solid'; - break; - case static::FORMAT_STRIKE: - $styles['style:text-line-through-type'] = 'single'; - break; - case static::FORMAT_ITALIC: - $styles['fo:font-style'] = 'italic'; - $styles['style:font-style-asian'] = 'italic'; - $styles['style:font-style-complex'] = 'italic'; - break; - case static::FORMAT_SUP: - $styles['fo:font-size'] = '10pt'; - $styles['style:text-position'] = '31%'; - break; - case static::FORMAT_SUB: - $styles['fo:font-size'] = '10pt'; - $styles['style:text-position'] = '-31%'; - break; - } - } - $this->appendTextStyleNode($name, $styles); - $this->classCache[$key] = $name; - } - return $this->classCache[$key]; - } - - /** - * @param string $html - * @return array - */ - public function html2OdsNodes($html) - { - $body = $this->html2DOM($html); - $tokens = $this->tokenizeFlattenHtml($body, []); - $nodes = []; - $currentP = $this->doc->createElementNS(static::NS_TEXT, 'p'); - foreach ($tokens as $token) { - if (trim($token['text']) != '') { - $node = $this->doc->createElement('text:span'); - if (count($token['formattings']) > 0) { - $className = $this->getClassByFormats($token['formattings']); - $node->setAttribute('text:style-name', $className); - } - $textNode = $this->doc->createTextNode($token['text']); - $node->appendChild($textNode); - $currentP->appendChild($node); - } - - if (in_array(static::FORMAT_LINEBREAK, $token['formattings'])) { - $nodes[] = $currentP; - $currentP = $this->doc->createElementNS(static::NS_TEXT, 'p'); - } - } - $nodes[] = $currentP; - return $nodes; - } - - - /** - * @return string - * @throws \Exception - */ - public function create() - { - $this->getCleanDomTable(); - $this->setColStyles(); - $this->setCellContent(); - $this->setRowStyles(); - $this->setCellStyles(); - - $xml = $this->doc->saveXML(); - - $rows = explode("\n", $xml); - $rows[0] .= "\n"; - return implode('', $rows) . "\n"; - } -} diff --git a/assets/html2opendocument/Text.php b/assets/html2opendocument/Text.php deleted file mode 100644 index 97b7ce1..0000000 --- a/assets/html2opendocument/Text.php +++ /dev/null @@ -1,583 +0,0 @@ - - * @license https://opensource.org/licenses/MIT - */ - -namespace CatoTH\HTML2OpenDocument; - -class Text extends Base -{ - /** @var null|\DOMElement */ - private $nodeText = null; - - /** @var bool */ - private $node_template_1_used = false; - - /** @var string[] */ - private $replaces = []; - - /** @var array */ - private $textBlocks = []; - - const STYLE_INS = 'ins'; - const STYLE_DEL = 'del'; - - /** - * @param array $options - * - * @throws \Exception - */ - public function __construct($options = []) - { - if (isset($options['templateFile']) && $options['templateFile'] != '') { - $templateFile = $options['templateFile']; - } else { - $templateFile = __DIR__ . DIRECTORY_SEPARATOR . 'default-template.odt'; - } - parent::__construct($templateFile, $options); - } - - /** - * @param string $filename - */ - public function finishAndOutputOdt($filename = '') - { - header('Content-Type: application/vnd.oasis.opendocument.text'); - if ($filename != '') { - header('Content-disposition: attachment;filename="' . addslashes($filename) . '"'); - } - - echo $this->finishAndGetDocument(); - - die(); - } - - /** - * @param string $search - * @param string $replace - */ - public function addReplace($search, $replace) - { - $this->replaces[$search] = $replace; - } - - /** - * @param string $html - * @param bool $lineNumbered - */ - public function addHtmlTextBlock($html, $lineNumbered = false) - { - $this->textBlocks[] = ['text' => $html, 'lineNumbered' => $lineNumbered]; - } - - /** - * @param \DOMElement $element - * @return string[] - */ - protected static function getCSSClasses(\DOMElement $element) - { - if ($element->hasAttribute('class')) { - return explode(' ', $element->getAttribute('class')); - } else { - return []; - } - } - - /** - * @param \DOMElement $element - * @param string[] $parentStyles - * @return string[] - */ - protected static function getChildStyles(\DOMElement $element, $parentStyles = []) - { - $classes = static::getCSSClasses($element); - $childStyles = $parentStyles; - if (in_array('ins', $classes)) { - $childStyles[] = static::STYLE_INS; - } - if (in_array('inserted', $classes)) { - $childStyles[] = static::STYLE_INS; - } - if (in_array('del', $classes)) { - $childStyles[] = static::STYLE_DEL; - } - if (in_array('deleted', $classes)) { - $childStyles[] = static::STYLE_DEL; - } - return array_unique($childStyles); - } - - /** - * @param string[] $classes - * - * @return null|string - */ - protected static function cssClassesToInternalClass($classes) - { - if (in_array('underline', $classes)) { - return 'AntragsgruenUnderlined'; - } - if (in_array('strike', $classes)) { - return 'AntragsgruenStrike'; - } - if (in_array('ins', $classes)) { - return 'AntragsgruenIns'; - } - if (in_array('inserted', $classes)) { - return 'AntragsgruenIns'; - } - if (in_array('del', $classes)) { - return 'AntragsgruenDel'; - } - if (in_array('deleted', $classes)) { - return 'AntragsgruenDel'; - } - if (in_array('superscript', $classes)) { - return 'AntragsgruenSup'; - } - if (in_array('subscript', $classes)) { - return 'AntragsgruenSub'; - } - return null; - } - - /** - * Wraps all child nodes with text:p nodes, if necessary - * (it's not necessary for child nodes that are p's themselves or lists) - * - * @param \DOMElement $parentEl - * @param boolean $lineNumbered - * - * @return \DOMElement - */ - protected function wrapChildrenWithP(\DOMElement $parentEl, $lineNumbered) - { - $childNodes = []; - while ($parentEl->childNodes->length > 0) { - $el = $parentEl->firstChild; - $parentEl->removeChild($el); - $childNodes[] = $el; - } - - $appendNode = null; - foreach ($childNodes as $childNode) { - if (in_array(strtolower($childNode->nodeName), ['p', 'list'])) { - if ($appendNode) { - $parentEl->appendChild($appendNode); - $appendNode = null; - } - $parentEl->appendChild($childNode); - } else { - if (!$appendNode) { - $appendNode = $this->getNextNodeTemplate($lineNumbered); - } - $appendNode->appendChild($childNode); - } - } - if ($appendNode) { - $parentEl->appendChild($appendNode); - } - - return $parentEl; - } - - /** - * @param \DOMNode $srcNode - * @param bool $lineNumbered - * @param bool $inP - * @param string[]   $parentStyles - * - * @return \DOMNode[] - * @throws \Exception - */ - protected function html2ooNodeInt($srcNode, $lineNumbered, $inP, $parentStyles = []) - { - switch ($srcNode->nodeType) { - case XML_ELEMENT_NODE: - /** @var \DOMElement $srcNode */ - if ($this->DEBUG) { - echo "Element - " . $srcNode->nodeName . " / Children: " . $srcNode->childNodes->length . "
"; - } - $needsIntermediateP = false; - $childStyles = static::getChildStyles($srcNode, $parentStyles); - switch ($srcNode->nodeName) { - case 'b': - case 'strong': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenBold'); - break; - case 'i': - case 'em': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenItalic'); - break; - case 's': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenStrike'); - break; - case 'u': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenUnderlined'); - break; - case 'sub': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenSub'); - break; - case 'sup': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenSup'); - break; - case 'br': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'line-break'); - break; - case 'del': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenDel'); - break; - case 'ins': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $dstEl->setAttribute('text:style-name', 'AntragsgruenIns'); - break; - case 'a': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'a'); - try { - $attr = $srcNode->getAttribute('href'); - if ($attr) { - $dstEl->setAttribute('xlink:href', $attr); - } - } catch (\Exception $e) { - } - break; - case 'p': - if ($inP) { - $dstEl = $this->createNodeWithBaseStyle('span', $lineNumbered); - } else { - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - } - $intClass = static::cssClassesToInternalClass(static::getCSSClasses($srcNode)); - if ($intClass) { - $dstEl->setAttribute('text:style-name', $intClass); - } - $inP = true; - break; - case 'div': - // We're basically ignoring DIVs here, as there is no corresponding element in OpenDocument - // Therefore no support for styles and classes set on DIVs yet. - $dstEl = null; - break; - case 'blockquote': - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - $class = ($lineNumbered ? 'Blockquote_Linenumbered' : 'Blockquote'); - $dstEl->setAttribute('text:style-name', 'Antragsgrün_20_' . $class); - if ($srcNode->childNodes->length == 1) { - foreach ($srcNode->childNodes as $child) { - if ($child->nodeName == 'p') { - $srcNode = $child; - } - } - } - $inP = true; - break; - case 'ul': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'list'); - break; - case 'ol': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'list'); - break; - case 'li': - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'list-item'); - $needsIntermediateP = true; - $inP = true; - break; - case 'h1': - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'Antragsgrün_20_H1'); - $inP = true; - break; - case 'h2': - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'Antragsgrün_20_H2'); - $inP = true; - break; - case 'h3': - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'Antragsgrün_20_H3'); - $inP = true; - break; - case 'h4': - case 'h5': - case 'h6': - $dstEl = $this->createNodeWithBaseStyle('p', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'Antragsgrün_20_H4'); - $inP = true; - break; - case 'span': - default: - $dstEl = $this->doc->createElementNS(static::NS_TEXT, 'span'); - $intClass = static::cssClassesToInternalClass(static::getCSSClasses($srcNode)); - if ($intClass) { - $dstEl->setAttribute('text:style-name', $intClass); - } - break; - } - - - if ($dstEl === null) { - $ret = []; - foreach ($srcNode->childNodes as $child) { - /** @var \DOMNode $child */ - if ($this->DEBUG) { - echo "CHILD
" . $child->nodeType . "
"; - } - - $dstNodes = $this->html2ooNodeInt($child, $lineNumbered, $inP, $childStyles); - foreach ($dstNodes as $dstNode) { - $ret[] = $dstNode; - } - } - return $ret; - } - - foreach ($srcNode->childNodes as $child) { - /** @var \DOMNode $child */ - if ($this->DEBUG) { - echo "CHILD
" . $child->nodeType . "
"; - } - - $dstNodes = $this->html2ooNodeInt($child, $lineNumbered, $inP, $childStyles); - foreach ($dstNodes as $dstNode) { - $dstEl->appendChild($dstNode); - } - } - - if ($needsIntermediateP && $dstEl->childNodes->length > 0) { - $dstEl = static::wrapChildrenWithP($dstEl, $lineNumbered); - } - return [$dstEl]; - case XML_TEXT_NODE: - /** @var \DOMText $srcNode */ - $textnode = new \DOMText(); - $textnode->data = $srcNode->data; - if ($this->DEBUG) { - echo 'Text
'; - } - if (in_array(static::STYLE_DEL, $parentStyles)) { - $dstEl = $this->createNodeWithBaseStyle('span', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'AntragsgruenDel'); - $dstEl->appendChild($textnode); - $textnode = $dstEl; - } - if (in_array(static::STYLE_INS, $parentStyles)) { - $dstEl = $this->createNodeWithBaseStyle('span', $lineNumbered); - $dstEl->setAttribute('text:style-name', 'AntragsgruenIns'); - $dstEl->appendChild($textnode); - $textnode = $dstEl; - } - return [$textnode]; - break; - case XML_DOCUMENT_TYPE_NODE: - if ($this->DEBUG) { - echo 'Type Node
'; - } - return []; - default: - if ($this->DEBUG) { - echo 'Unknown Node: ' . $srcNode->nodeType . '
'; - } - return []; - } - } - - /** - * @param string $html - * @param bool $lineNumbered - * - * @return \DOMNode[] - * @throws \Exception - */ - protected function html2ooNodes($html, $lineNumbered) - { - if (!is_string($html)) { - echo print_r($html, true); - echo print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), true); - die(); - } - - $body = $this->html2DOM($html); - - $retNodes = []; - for ($i = 0; $i < $body->childNodes->length; $i++) { - $child = $body->childNodes->item($i); - - /** @var \DOMNode $child */ - if ($child->nodeName == 'ul') { - // Alle anderen Nodes dieses Aufrufs werden ignoriert - if ($this->DEBUG) { - echo 'LIST
'; - } - $recNewNodes = $this->html2ooNodeInt($child, $lineNumbered, false); - } else { - if ($child->nodeType == XML_TEXT_NODE) { - $new_node = $this->getNextNodeTemplate($lineNumbered); - /** @var \DOMText $child */ - if ($this->DEBUG) { - echo $child->nodeName . ' - ' . htmlentities($child->data, ENT_COMPAT, 'UTF-8') . '
'; - } - $text = new \DOMText(); - $text->data = $child->data; - $new_node->appendChild($text); - $recNewNodes = [$new_node]; - } else { - if ($this->DEBUG) { - echo $child->nodeName . '!!!!!!!!!!!!
'; - } - $recNewNodes = $this->html2ooNodeInt($child, $lineNumbered, false); - } - } - foreach ($recNewNodes as $recNewNode) { - $retNodes[] = $recNewNode; - } - } - - return $retNodes; - } - - /** - * @return string - * @throws \Exception - */ - public function create() - { - $this->appendTextStyleNode('AntragsgruenBold', [ - 'fo:font-weight' => 'bold', - 'style:font-weight-asian' => 'bold', - 'style:font-weight-complex' => 'bold', - ]); - $this->appendTextStyleNode('AntragsgruenItalic', [ - 'fo:font-style' => 'italic', - 'style:font-style-asian' => 'italic', - 'style:font-style-complex' => 'italic', - ]); - $this->appendTextStyleNode('AntragsgruenUnderlined', [ - 'style:text-underline-width' => 'auto', - 'style:text-underline-color' => 'font-color', - 'style:text-underline-style' => 'solid', - ]); - $this->appendTextStyleNode('AntragsgruenStrike', [ - 'style:text-line-through-style' => 'solid', - 'style:text-line-through-type' => 'single', - ]); - $this->appendTextStyleNode('AntragsgruenIns', [ - 'fo:color' => '#008800', - 'style:text-underline-style' => 'solid', - 'style:text-underline-width' => 'auto', - 'style:text-underline-color' => 'font-color', - 'fo:font-weight' => 'bold', - 'style:font-weight-asian' => 'bold', - 'style:font-weight-complex' => 'bold', - ]); - $this->appendTextStyleNode('AntragsgruenDel', [ - 'fo:color' => '#880000', - 'style:text-line-through-style' => 'solid', - 'style:text-line-through-type' => 'single', - 'fo:font-style' => 'italic', - 'style:font-style-asian' => 'italic', - 'style:font-style-complex' => 'italic', - ]); - $this->appendTextStyleNode('AntragsgruenSub', [ - 'style:text-position' => 'sub 58%', - ]); - $this->appendTextStyleNode('AntragsgruenSup', [ - 'style:text-position' => 'super 58%', - ]); - - /** @var \DOMNode[] $nodes */ - $nodes = []; - foreach ($this->doc->getElementsByTagNameNS(static::NS_TEXT, 'span') as $element) { - $nodes[] = $element; - } - foreach ($this->doc->getElementsByTagNameNS(static::NS_TEXT, 'p') as $element) { - $nodes[] = $element; - } - - - $searchFor = array_keys($this->replaces); - $replaceWith = array_values($this->replaces); - foreach ($nodes as $node) { - $children = $node->childNodes; - foreach ($children as $child) { - if ($child->nodeType == XML_TEXT_NODE) { - /** @var \DOMText $child */ - $child->data = preg_replace($searchFor, $replaceWith, $child->data); - - if (preg_match("/\{\{ANTRAGSGRUEN:DUMMY\}\}/siu", $child->data)) { - $node->parentNode->removeChild($node); - } - if (preg_match("/\{\{ANTRAGSGRUEN:TEXT\}\}/siu", $child->data)) { - $this->nodeText = $node; - } - } - } - } - - foreach ($this->textBlocks as $textBlock) { - $newNodes = $this->html2ooNodes($textBlock['text'], $textBlock['lineNumbered']); - foreach ($newNodes as $newNode) { - $this->nodeText->parentNode->insertBefore($newNode, $this->nodeText); - } - } - - $this->nodeText->parentNode->removeChild($this->nodeText); - - return $this->doc->saveXML(); - } - - /** - * @param bool $lineNumbers - * - * @return \DOMNode - */ - protected function getNextNodeTemplate($lineNumbers) - { - $node = $this->nodeText->cloneNode(); - /** @var \DOMElement $node */ - if ($lineNumbers) { - if ($this->node_template_1_used) { - $node->setAttribute('text:style-name', 'Antragsgrün_20_LineNumbered_20_Standard'); - } else { - $this->node_template_1_used = true; - $node->setAttribute('text:style-name', 'Antragsgrün_20_LineNumbered_20_First'); - } - } else { - $node->setAttribute('text:style-name', 'Antragsgrün_20_Standard'); - } - - return $node; - } - - /** - * @param string $nodeType - * @param bool $lineNumbers - * - * @return \DOMElement|\DOMNode - */ - protected function createNodeWithBaseStyle($nodeType, $lineNumbers) - { - $node = $this->doc->createElementNS(static::NS_TEXT, $nodeType); - if ($lineNumbers) { - if ($this->node_template_1_used) { - $node->setAttribute('text:style-name', 'Antragsgrün_20_LineNumbered_20_Standard'); - } else { - $this->node_template_1_used = true; - $node->setAttribute('text:style-name', 'Antragsgrün_20_LineNumbered_20_First'); - } - } else { - $node->setAttribute('text:style-name', 'Antragsgrün_20_Standard'); - } - - return $node; - } -} diff --git a/assets/html2opendocument/composer.json b/assets/html2opendocument/composer.json deleted file mode 100644 index c36bfef..0000000 --- a/assets/html2opendocument/composer.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "catoth/html2opendocument", - "description": "Converting simple HTML to Opendocument Text (ODT) or Spreadsheets (ODS)", - "type": "library", - "minimum-stability": "stable", - "license": "MIT", - "keywords": [ - "opendocument", - "html", - "odt", - "ods" - ], - "authors": [ - { - "name": "Tobias Hößl", - "email": "tobias@hoessl.eu" - } - ], - "require": { - "php": ">=5.5.0", - "ext-zip": "*", - "ext-dom": "*", - "ezyang/htmlpurifier": "*" - }, - "autoload": { - "psr-4": { - "CatoTH\\HTML2OpenDocument\\": "" - } - } -} diff --git a/assets/html2opendocument/default-template-with-replaces.odt b/assets/html2opendocument/default-template-with-replaces.odt deleted file mode 100644 index 133ea57657274b4009ebe65a9c38c44f2d613ed2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18589 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 uHSvEx`~4&FEB#O6AD#sNtM|pnx>;C|!QB>3b diff --git a/assets/html2opendocument/default-template.ods b/assets/html2opendocument/default-template.ods deleted file mode 100644 index a4e37a3771ddf77caa9ce0c035d19b8eed85e310..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11004 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 YtSpZPubGgLh~PiAsPO8E9`V=z0J-i+x&QzG diff --git a/assets/html2opendocument/default-template.odt b/assets/html2opendocument/default-template.odt deleted file mode 100644 index cda6295cd1df5f0db79c00c9ab994c10cba3d5c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9627 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 JOyY-c{{!MxrF#GX diff --git a/assets/html2opendocument/demo2.php b/assets/html2opendocument/demo2.php deleted file mode 100644 index 2176ad7..0000000 --- a/assets/html2opendocument/demo2.php +++ /dev/null @@ -1,50 +0,0 @@ -setCell(0, 0, Spreadsheet::TYPE_TEXT, 'Plain text with native formatting'); -$ods->setCellStyle(0, 0, [], ['fo:font-weight' => 'bold']); - -// Print a number as an actual number, just a little bit bigger -$ods->setCell(1, 0, Spreadsheet::TYPE_NUMBER, 23); -$ods->setCellStyle(1, 0, [], [ - 'fo:font-size' => '16pt', - 'fo:font-weight' => 'bold', -]); -$ods->setMinRowHeight(1, 1.5); - -// Print a number as text -$ods->setCell(2, 0, Spreadsheet::TYPE_TEXT, '42'); - -// Draw a border around two of the cells -$ods->drawBorder(1, 0, 2, 0, 1); - - -// Now we use HTML, and we need a bit more space for that -$html = '

The converter supports the following styles:

-
    -
  • STRONG
  • -
  • U (underlined)
  • -
  • S (strike-through)
  • -
  • EM (emphasis / italic)
  • -
  • Inserted text
  • -
  • Deleted text
  • -
  • Line
    breaks with BR
  • -
  • Lists (UL / OL) cannot be displayed as lists, but will be flattened to paragraphs
  • -
-
You can also use BLOCKQUOTE, though it lacks specific styling for now
'; - -$ods->setMinRowHeight(3, 10); -$ods->setColumnWidth(1, 20); -$ods->setCell(3, 1, Spreadsheet::TYPE_HTML, $html); - - -$ods->finishAndOutputOds('demo.ods'); - -?> \ No newline at end of file diff --git a/readme.md b/readme.md index 5a1abce..5010495 100644 --- a/readme.md +++ b/readme.md @@ -1,4 +1,4 @@ -#Libreto +# Libreto ![Libreto](http://libreto.net/assets/images/libretonet.png)