Skip to content

Commit 083769d

Browse files
committed
Changed internallink() implementation for exporting books:
If the target of an internal link is one of the exported pages, then an ODT document internal/local link will be cretaed. Otherwise an external link will be created (like before).
1 parent 0b93698 commit 083769d

File tree

2 files changed

+152
-14
lines changed

2 files changed

+152
-14
lines changed

renderer/book.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,20 @@ class renderer_plugin_odt_book extends renderer_plugin_odt_page {
1717
protected $wikipages_count = 0;
1818
/** @var string document title*/
1919
protected $title = '';
20+
/**
21+
* Stores action instance
22+
*
23+
* @var action_plugin_dw2pdf
24+
*/
25+
private $actioninstance = null;
26+
27+
/**
28+
* load action plugin instance
29+
*/
30+
public function __construct() {
31+
parent::__construct();
32+
$this->actioninstance = plugin_load('action', 'odt');
33+
}
2034

2135
/**
2236
* clean out any per-use values
@@ -32,6 +46,8 @@ public function reset() {
3246
* Initialize the document
3347
*/
3448
public function document_start() {
49+
global $ID;
50+
3551
// number of wiki pages included in ODT file
3652
$this->wikipages_count ++;
3753

@@ -40,6 +56,7 @@ public function document_start() {
4056
parent::document_start();
4157
} else {
4258
$this->pagebreak();
59+
$this->insert_bookmark($ID);
4360
}
4461
}
4562

@@ -88,4 +105,45 @@ public function isBookStart() {
88105
public function setTitle($title) {
89106
$this->title = $title;
90107
}
108+
109+
/**
110+
* Render a wiki internal link.
111+
* In book export mode a local link with a name/test will be inserted if the
112+
* referenced page is included in the exported pages. Otherwise an external
113+
* link will be created.
114+
*
115+
* @param string $id page ID to link to. eg. 'wiki:syntax'
116+
* @param string|array $name name for the link, array for media file
117+
*
118+
* @author Andreas Gohr <andi@splitbrain.org>, LarsDW223
119+
*/
120+
function internallink($id, $name = NULL) {
121+
global $ID;
122+
// default name is based on $id as given
123+
$default = $this->_simpleTitle($id);
124+
// now first resolve and clean up the $id
125+
resolve_pageid(getNS($ID),$id,$exists);
126+
$name = $this->_getLinkTitle($name, $default, $isImage, $id);
127+
128+
// build the absolute URL (keeping a hash if any)
129+
list($id,$hash) = explode('#',$id,2);
130+
131+
// Is the link a link to a page included in the book?
132+
$pages = $this->actioninstance->getExportedPages();
133+
if ( in_array($id, $pages) ) {
134+
// Yes, create a local link with a name
135+
parent::locallink_with_name($hash, $id, $name);
136+
return;
137+
}
138+
139+
// No, create an external link
140+
$url = wl($id,'',true);
141+
if($hash) $url .='#'.$hash;
142+
143+
if ($ID == $id) {
144+
$this->reference($hash, $name);
145+
} else {
146+
$this->_doLink($url,$name);
147+
}
148+
}
91149
}

renderer/page.php

Lines changed: 94 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
class renderer_plugin_odt_page extends Doku_Renderer {
2626
/** @var array store the table of contents */
2727
protected $toc = array();
28+
/** @var array store the bookmarks */
29+
protected $bookmarks = array();
2830
/** @var array store the table of contents */
2931
public $toc_settings = 'leader-sign=.;';
3032
/** @var export mode (scratch or ODT template) */
@@ -252,6 +254,8 @@ function document_start() {
252254
header('Content-Type: application/vnd.oasis.opendocument.text');
253255
header('Content-Disposition: attachment; filename="'.$output_filename.'";');
254256
}
257+
258+
$this->insert_bookmark($ID);
255259
}
256260

257261
/**
@@ -716,6 +720,18 @@ function p_close(){
716720
}
717721
}
718722

723+
/**
724+
* Insert a bookmark.
725+
*
726+
* @param string $id ID of the bookmark
727+
*/
728+
function insert_bookmark($id){
729+
$this->p_open();
730+
$this->doc .= '<text:bookmark text:name="'.$id.'"/>';
731+
$this->p_close();
732+
$this->bookmarks [] = $id;
733+
}
734+
719735
/**
720736
* Render a heading
721737
*
@@ -1436,34 +1452,98 @@ function externallink($url, $name = NULL) {
14361452
*/
14371453
protected function insert_locallinks() {
14381454
$matches = array();
1439-
if ( preg_match('/<locallink>.+<\/locallink>/', $this->doc, $matches) === 1 ) {
1440-
foreach ($matches as $match) {
1441-
$text = substr ($match, 11);
1442-
$text = str_replace ('</locallink>', '', $text);
1443-
$page = str_replace (' ', '_', $text);
1444-
1445-
$found = false;
1446-
foreach ($this->toc as $item) {
1447-
$params = explode (',', $item);
1448-
if ( $page == $params [1] ) {
1455+
$position = 0;
1456+
$max = strlen ($this->doc);
1457+
$length = strlen ('<locallink>');
1458+
$length_with_name = strlen ('<locallink name=');
1459+
while ( $position < $max ) {
1460+
$first = strpos ($this->doc, '<locallink', $position);
1461+
if ( $first === false ) {
1462+
break;
1463+
}
1464+
$end_first = strpos ($this->doc, '>', $first);
1465+
if ( $end_first === false ) {
1466+
break;
1467+
}
1468+
$second = strpos ($this->doc, '</locallink>', $end_first);
1469+
if ( $second === false ) {
1470+
break;
1471+
}
1472+
1473+
// $match includes the whole tag '<locallink name="...">text</locallink>'
1474+
// The attribute 'name' is optional!
1475+
$match = substr ($this->doc, $first, $second - $first + $length + 1);
1476+
$text = substr ($match, $end_first-$first+1, -($length + 1));
1477+
$page = str_replace (' ', '_', $text);
1478+
$opentag = substr ($match, 0, $end_first-$first);
1479+
$name = substr ($opentag, $length_with_name);
1480+
$name = trim ($name, '">');
1481+
1482+
$found = false;
1483+
foreach ($this->toc as $item) {
1484+
$params = explode (',', $item);
1485+
if ( $page == $params [1] ) {
1486+
$found = true;
1487+
$link = '<text:a xlink:type="simple" xlink:href="#'.$params [0].'">';
1488+
$link .= $text;
1489+
$link .= '</text:a>';
1490+
1491+
$this->doc = str_replace ($match, $link, $this->doc);
1492+
$position = $first + strlen ($link);
1493+
}
1494+
}
1495+
1496+
if ( $found == false ) {
1497+
// Nothing found yet, check the bookmarks too.
1498+
foreach ($this->bookmarks as $item) {
1499+
if ( $page == $item ) {
14491500
$found = true;
1450-
$link = '<text:a xlink:type="simple" xlink:href="#'.$params [0].'">';
1451-
$link .= $text;
1501+
$link = '<text:a xlink:type="simple" xlink:href="#'.$item.'">';
1502+
if ( !empty($name) ) {
1503+
$link .= $name;
1504+
} else {
1505+
$link .= $text;
1506+
}
14521507
$link .= '</text:a>';
14531508

14541509
$this->doc = str_replace ($match, $link, $this->doc);
1510+
$position = $first + strlen ($link);
14551511
}
14561512
}
1513+
}
14571514

1458-
if ( $found == false ) {
1515+
if ( $found == false ) {
1516+
// If we get here, then the referenced target was not found.
1517+
// There must be a bug manging the bookmarks or links!
1518+
// At least remove the locallink element and insert text.
1519+
if ( !empty($name) ) {
1520+
$this->doc = str_replace ($match, $name, $this->doc);
1521+
} else {
14591522
$this->doc = str_replace ($match, $text, $this->doc);
14601523
}
1524+
$position = $first + strlen ($text);
14611525
}
14621526
}
14631527
}
14641528

14651529
/**
1466-
* Just print local links
1530+
* Insert local link placeholder with name.
1531+
* The reference will be resolved on calling insert_locallinks();
1532+
*
1533+
* @fixme add image handling
1534+
*
1535+
* @param string $hash hash link identifier
1536+
* @param string $id name for the link (the reference)
1537+
* @param string $name text for the link (text inserted instead of reference)
1538+
*/
1539+
function locallink_with_name($hash, $id = NULL, $name = NULL){
1540+
$id = $this->_getLinkTitle($id, $hash, $isImage);
1541+
$this->doc .= '<locallink name="'.$name.'">'.$id.'</locallink>';
1542+
}
1543+
1544+
/**
1545+
* Insert local link placeholder.
1546+
* The reference will be resolved on calling insert_locallinks();
14671547
*
14681548
* @fixme add image handling
14691549
*

0 commit comments

Comments
 (0)