Skip to content

Commit e911987

Browse files
potofcoffeecodex
andcommitted
feat: support native ODText bookmarks
Serialize PHPWord point bookmarks as native ODF text bookmarks and add regression coverage and documentation. Co-authored-by: Codex <noreply@openai.com>
1 parent 1240055 commit e911987

4 files changed

Lines changed: 98 additions & 1 deletion

File tree

docs/usage/elements/bookmark.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Bookmark
2+
3+
Bookmarks identify a position in a document so that fields and links can refer to it.
4+
5+
``` php
6+
<?php
7+
8+
$section->addBookmark('introduction');
9+
```
10+
11+
The ODText writer serializes bookmarks as native ODF point bookmarks. Bookmark ranges and cross-reference fields are separate features.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ nav:
5353
- Chart: 'usage/elements/chart.md'
5454
- Checkbox: 'usage/elements/checkbox.md'
5555
- Comment: 'usage/elements/comment.md'
56+
- Bookmark: 'usage/elements/bookmark.md'
5657
- Field: 'usage/elements/field.md'
5758
- Footnote & Endnote: 'usage/elements/note.md'
5859
- Formula: 'usage/elements/formula.md'
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/**
4+
* This file is part of PHPWord - A pure PHP library for reading and writing
5+
* word processing documents.
6+
*
7+
* PHPWord is free software distributed under the terms of the GNU Lesser
8+
* General Public License as published by the Free Software Foundation.
9+
*
10+
* For the full copyright and license information, please read the LICENSE
11+
* file that was distributed with this source code. For the full list of
12+
* contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
13+
*
14+
* @see https://github.com/PHPOffice/PHPWord
15+
*
16+
* @license http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17+
*/
18+
19+
namespace PhpOffice\PhpWord\Writer\ODText\Element;
20+
21+
/**
22+
* Bookmark element writer.
23+
*/
24+
class Bookmark extends AbstractElement
25+
{
26+
/**
27+
* Write bookmark element.
28+
*/
29+
public function write(): void
30+
{
31+
$xmlWriter = $this->getXmlWriter();
32+
$element = $this->getElement();
33+
if (!$element instanceof \PhpOffice\PhpWord\Element\Bookmark) {
34+
return;
35+
}
36+
37+
if (!$this->withoutP) {
38+
$xmlWriter->startElement('text:p');
39+
}
40+
41+
$xmlWriter->startElement('text:bookmark');
42+
$xmlWriter->writeAttribute('text:name', $element->getName());
43+
$xmlWriter->endElement();
44+
45+
if (!$this->withoutP) {
46+
$xmlWriter->endElement();
47+
}
48+
}
49+
}

tests/PhpWordTests/Writer/ODText/ElementTest.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,44 @@ public function testUnmatchedElements(): void
5656
}
5757
}
5858

59+
/**
60+
* Test bookmark element.
61+
*/
62+
public function testBookmarkElement(): void
63+
{
64+
$phpWord = new PhpWord();
65+
$section = $phpWord->addSection();
66+
$section->addBookmark('test_bookmark');
67+
68+
$doc = TestHelperDOCX::getDocument($phpWord, 'ODText');
69+
70+
$path = '/office:document-content/office:body/office:text/text:section/text:p/text:bookmark';
71+
self::assertTrue($doc->elementExists($path));
72+
self::assertEquals('test_bookmark', $doc->getElementAttribute($path, 'text:name'));
73+
}
74+
75+
/**
76+
* Test multiple bookmarks and bookmarks in text runs.
77+
*/
78+
public function testMultipleBookmarksAndNestedBookmarkElement(): void
79+
{
80+
$phpWord = new PhpWord();
81+
$section = $phpWord->addSection();
82+
$section->addBookmark('first_bookmark');
83+
$section->addBookmark('bookmark_with_&');
84+
$textRun = $section->addTextRun();
85+
$textRun->addBookmark('nested_bookmark');
86+
87+
$doc = TestHelperDOCX::getDocument($phpWord, 'ODText');
88+
89+
$path = '/office:document-content/office:body/office:text/text:section//text:bookmark';
90+
self::assertTrue($doc->elementExists("($path)[3]"));
91+
self::assertEquals('first_bookmark', $doc->getElementAttribute("($path)[1]", 'text:name'));
92+
self::assertEquals('bookmark_with_&', $doc->getElementAttribute("($path)[2]", 'text:name'));
93+
self::assertEquals('nested_bookmark', $doc->getElementAttribute("($path)[3]", 'text:name'));
94+
}
95+
5996
// ODT Line Element not yet implemented
60-
// ODT Bookmark not yet implemented
6197
// ODT Table with style name not yet implemented (Word test defective)
6298
// ODT Shape Elements not yet implemented
6399
// ODT Chart Elements not yet implemented

0 commit comments

Comments
 (0)