xref: /dokuwiki/inc/parser/metadata.php (revision 93075b016d22b16e7d11cd93fac9a54e91e22269)
139a89382SEsther Brunner<?php
239a89382SEsther Brunner/**
339a89382SEsther Brunner * Renderer for metadata
439a89382SEsther Brunner *
539a89382SEsther Brunner * @author Esther Brunner <wikidesign@gmail.com>
639a89382SEsther Brunner */
7fa8adffeSAndreas Gohrif(!defined('DOKU_INC')) die('meh.');
839a89382SEsther Brunner
939a89382SEsther Brunnerif(!defined('DOKU_LF')) {
1039a89382SEsther Brunner    // Some whitespace to help View > Source
1139a89382SEsther Brunner    define ('DOKU_LF', "\n");
1239a89382SEsther Brunner}
1339a89382SEsther Brunner
1439a89382SEsther Brunnerif(!defined('DOKU_TAB')) {
1539a89382SEsther Brunner    // Some whitespace to help View > Source
1639a89382SEsther Brunner    define ('DOKU_TAB', "\t");
1739a89382SEsther Brunner}
1839a89382SEsther Brunner
1939a89382SEsther Brunner/**
20*93075b01SAndreas Gohr * The MetaData Renderer
21*93075b01SAndreas Gohr *
22*93075b01SAndreas Gohr * Metadata is additional information about a DokuWiki page that gets extracted mainly from the page's content
23*93075b01SAndreas Gohr * but also it's own filesystem data (like the creation time). All metadata is stored in the fields $meta and
24*93075b01SAndreas Gohr * $persistent.
25*93075b01SAndreas Gohr *
26*93075b01SAndreas Gohr * Some simplified rendering to $doc is done to gather the page's (text-only) abstract.
2739a89382SEsther Brunner */
2839a89382SEsther Brunnerclass Doku_Renderer_metadata extends Doku_Renderer {
2939a89382SEsther Brunner
30*93075b01SAndreas Gohr    /** @var array transient meta data, will be reset on each rendering */
31*93075b01SAndreas Gohr    public $meta = array();
3239a89382SEsther Brunner
33*93075b01SAndreas Gohr    /** @var array persistent meta data, will be kept until explicitly deleted */
34*93075b01SAndreas Gohr    public $persistent = array();
3539a89382SEsther Brunner
36*93075b01SAndreas Gohr    /** @var array the list of headers used to create unique link ids */
37*93075b01SAndreas Gohr    protected $headers = array();
38*93075b01SAndreas Gohr
39*93075b01SAndreas Gohr    /** @var bool determines if enough data for a page summary was collected, yet */
40*93075b01SAndreas Gohr    protected $capture = true;
41*93075b01SAndreas Gohr
42*93075b01SAndreas Gohr    /** @var string temporary $doc store */
43*93075b01SAndreas Gohr    protected $store = '';
44*93075b01SAndreas Gohr
45*93075b01SAndreas Gohr    /** @var string keeps the first image reference */
46*93075b01SAndreas Gohr    protected $firstimage = '';
47*93075b01SAndreas Gohr
48*93075b01SAndreas Gohr    /**
49*93075b01SAndreas Gohr     * Returns the format produced by this renderer.
50*93075b01SAndreas Gohr     *
51*93075b01SAndreas Gohr     * @return string always 'metadata'
52*93075b01SAndreas Gohr     */
535f70445dSAndreas Gohr    function getFormat() {
545f70445dSAndreas Gohr        return 'metadata';
555f70445dSAndreas Gohr    }
565f70445dSAndreas Gohr
57*93075b01SAndreas Gohr    /**
58*93075b01SAndreas Gohr     * Initialize the document
59*93075b01SAndreas Gohr     *
60*93075b01SAndreas Gohr     * Sets up some of the persistent info about the page if it doesn't exist, yet.
61*93075b01SAndreas Gohr     */
6239a89382SEsther Brunner    function document_start() {
63ef47e298SAndreas Gohr        global $ID;
64620f4930SAndreas Gohr
65620f4930SAndreas Gohr        $this->headers = array();
66620f4930SAndreas Gohr
67ef47e298SAndreas Gohr        // external pages are missing create date
68ef47e298SAndreas Gohr        if(!$this->persistent['date']['created']) {
69ef47e298SAndreas Gohr            $this->persistent['date']['created'] = filectime(wikiFN($ID));
70ef47e298SAndreas Gohr        }
71a8e72133SAndreas Gohr        if(!isset($this->persistent['user'])) {
72a8e72133SAndreas Gohr            $this->persistent['user'] = '';
73a8e72133SAndreas Gohr        }
74ef47e298SAndreas Gohr        if(!isset($this->persistent['creator'])) {
75ef47e298SAndreas Gohr            $this->persistent['creator'] = '';
76ef47e298SAndreas Gohr        }
770a7e3bceSchris        // reset metadata to persistent values
780a7e3bceSchris        $this->meta = $this->persistent;
7939a89382SEsther Brunner    }
8039a89382SEsther Brunner
81*93075b01SAndreas Gohr    /**
82*93075b01SAndreas Gohr     * Finalize the document
83*93075b01SAndreas Gohr     *
84*93075b01SAndreas Gohr     * Stores collected data in the metadata
85*93075b01SAndreas Gohr     */
8639a89382SEsther Brunner    function document_end() {
87482cff99SAndreas Gohr        global $ID;
88482cff99SAndreas Gohr
89b8595a66SAndreas Gohr        // store internal info in metadata (notoc,nocache)
90b8595a66SAndreas Gohr        $this->meta['internal'] = $this->info;
91b8595a66SAndreas Gohr
92c66972f2SAdrian Lang        if(!isset($this->meta['description']['abstract'])) {
9339a89382SEsther Brunner            // cut off too long abstracts
9439a89382SEsther Brunner            $this->doc = trim($this->doc);
9539a89382SEsther Brunner            if(strlen($this->doc) > 500)
96bc769d32SAndreas Gohr                $this->doc = utf8_substr($this->doc, 0, 500).'…';
9739a89382SEsther Brunner            $this->meta['description']['abstract'] = $this->doc;
9839a89382SEsther Brunner        }
99aa5a2937SAndreas Gohr
100aa5a2937SAndreas Gohr        $this->meta['relation']['firstimage'] = $this->firstimage;
101482cff99SAndreas Gohr
102c0322273SAdrian Lang        if(!isset($this->meta['date']['modified'])) {
103482cff99SAndreas Gohr            $this->meta['date']['modified'] = filemtime(wikiFN($ID));
104482cff99SAndreas Gohr        }
105482cff99SAndreas Gohr
10639a89382SEsther Brunner    }
10739a89382SEsther Brunner
108*93075b01SAndreas Gohr    /**
109*93075b01SAndreas Gohr     * Add an item to the TOC
110*93075b01SAndreas Gohr     *
111*93075b01SAndreas Gohr     * @param string $id       the hash link
112*93075b01SAndreas Gohr     * @param string $text     the text to display
113*93075b01SAndreas Gohr     * @param int    $level    the nesting level
114*93075b01SAndreas Gohr     */
115e7856beaSchris    function toc_additem($id, $text, $level) {
11639a89382SEsther Brunner        global $conf;
11739a89382SEsther Brunner
118e7856beaSchris        //only add items within configured levels
11939a89382SEsther Brunner        if($level >= $conf['toptoclevel'] && $level <= $conf['maxtoclevel']) {
12039a89382SEsther Brunner            // the TOC is one of our standard ul list arrays ;-)
12139a89382SEsther Brunner            $this->meta['description']['tableofcontents'][] = array(
122e7856beaSchris                'hid'   => $id,
12339a89382SEsther Brunner                'title' => $text,
12439a89382SEsther Brunner                'type'  => 'ul',
12539a89382SEsther Brunner                'level' => $level - $conf['toptoclevel'] + 1
12639a89382SEsther Brunner            );
12739a89382SEsther Brunner        }
12839a89382SEsther Brunner
129e7856beaSchris    }
130e7856beaSchris
131*93075b01SAndreas Gohr    /**
132*93075b01SAndreas Gohr     * Render a heading
133*93075b01SAndreas Gohr     *
134*93075b01SAndreas Gohr     * @param string $text  the text to display
135*93075b01SAndreas Gohr     * @param int    $level header level
136*93075b01SAndreas Gohr     * @param int    $pos   byte position in the original source
137*93075b01SAndreas Gohr     */
138e7856beaSchris    function header($text, $level, $pos) {
139c66972f2SAdrian Lang        if(!isset($this->meta['title'])) $this->meta['title'] = $text;
140e7856beaSchris
141e7856beaSchris        // add the header to the TOC
142e7856beaSchris        $hid = $this->_headerToLink($text, 'true');
143e7856beaSchris        $this->toc_additem($hid, $text, $level);
144e7856beaSchris
14539a89382SEsther Brunner        // add to summary
14639a89382SEsther Brunner        if($this->capture && ($level > 1)) $this->doc .= DOKU_LF.$text.DOKU_LF;
14739a89382SEsther Brunner    }
14839a89382SEsther Brunner
149*93075b01SAndreas Gohr    /**
150*93075b01SAndreas Gohr     * Render plain text data
151*93075b01SAndreas Gohr     *
152*93075b01SAndreas Gohr     * @param $text
153*93075b01SAndreas Gohr     */
15439a89382SEsther Brunner    function cdata($text) {
15539a89382SEsther Brunner        if($this->capture) $this->doc .= $text;
15639a89382SEsther Brunner    }
15739a89382SEsther Brunner
158*93075b01SAndreas Gohr    /**
159*93075b01SAndreas Gohr     * Open a paragraph
160*93075b01SAndreas Gohr     */
16139a89382SEsther Brunner    function p_open() {
16239a89382SEsther Brunner        if($this->capture) $this->doc .= DOKU_LF;
16339a89382SEsther Brunner    }
16439a89382SEsther Brunner
165*93075b01SAndreas Gohr    /**
166*93075b01SAndreas Gohr     * Close a paragraph
167*93075b01SAndreas Gohr     */
16839a89382SEsther Brunner    function p_close() {
16939a89382SEsther Brunner        if($this->capture) {
17039a89382SEsther Brunner            if(strlen($this->doc) > 250) $this->capture = false;
17139a89382SEsther Brunner            else $this->doc .= DOKU_LF;
17239a89382SEsther Brunner        }
17339a89382SEsther Brunner    }
17439a89382SEsther Brunner
175*93075b01SAndreas Gohr    /**
176*93075b01SAndreas Gohr     * Create a line break
177*93075b01SAndreas Gohr     */
17839a89382SEsther Brunner    function linebreak() {
17939a89382SEsther Brunner        if($this->capture) $this->doc .= DOKU_LF;
18039a89382SEsther Brunner    }
18139a89382SEsther Brunner
182*93075b01SAndreas Gohr    /**
183*93075b01SAndreas Gohr     * Create a horizontal line
184*93075b01SAndreas Gohr     */
18539a89382SEsther Brunner    function hr() {
18639a89382SEsther Brunner        if($this->capture) {
18739a89382SEsther Brunner            if(strlen($this->doc) > 250) $this->capture = false;
18839a89382SEsther Brunner            else $this->doc .= DOKU_LF.'----------'.DOKU_LF;
18939a89382SEsther Brunner        }
19039a89382SEsther Brunner    }
19139a89382SEsther Brunner
19239a89382SEsther Brunner    /**
19339a89382SEsther Brunner     * Callback for footnote start syntax
19439a89382SEsther Brunner     *
19539a89382SEsther Brunner     * All following content will go to the footnote instead of
19639a89382SEsther Brunner     * the document. To achieve this the previous rendered content
19739a89382SEsther Brunner     * is moved to $store and $doc is cleared
19839a89382SEsther Brunner     *
19939a89382SEsther Brunner     * @author Andreas Gohr <andi@splitbrain.org>
20039a89382SEsther Brunner     */
20139a89382SEsther Brunner    function footnote_open() {
20239a89382SEsther Brunner        if($this->capture) {
20339a89382SEsther Brunner            // move current content to store and record footnote
20439a89382SEsther Brunner            $this->store = $this->doc;
20539a89382SEsther Brunner            $this->doc   = '';
20639a89382SEsther Brunner        }
20739a89382SEsther Brunner    }
20839a89382SEsther Brunner
20939a89382SEsther Brunner    /**
21039a89382SEsther Brunner     * Callback for footnote end syntax
21139a89382SEsther Brunner     *
21239a89382SEsther Brunner     * All rendered content is moved to the $footnotes array and the old
21339a89382SEsther Brunner     * content is restored from $store again
21439a89382SEsther Brunner     *
21539a89382SEsther Brunner     * @author Andreas Gohr
21639a89382SEsther Brunner     */
21739a89382SEsther Brunner    function footnote_close() {
21839a89382SEsther Brunner        if($this->capture) {
21939a89382SEsther Brunner            // restore old content
22039a89382SEsther Brunner            $this->doc   = $this->store;
22139a89382SEsther Brunner            $this->store = '';
22239a89382SEsther Brunner        }
22339a89382SEsther Brunner    }
22439a89382SEsther Brunner
225*93075b01SAndreas Gohr    /**
226*93075b01SAndreas Gohr     * Open an unordered list
227*93075b01SAndreas Gohr     */
22839a89382SEsther Brunner    function listu_open() {
22939a89382SEsther Brunner        if($this->capture) $this->doc .= DOKU_LF;
23039a89382SEsther Brunner    }
23139a89382SEsther Brunner
232*93075b01SAndreas Gohr    /**
233*93075b01SAndreas Gohr     * Close an unordered list
234*93075b01SAndreas Gohr     */
23539a89382SEsther Brunner    function listu_close() {
23639a89382SEsther Brunner        if($this->capture && (strlen($this->doc) > 250)) $this->capture = false;
23739a89382SEsther Brunner    }
23839a89382SEsther Brunner
239*93075b01SAndreas Gohr    /**
240*93075b01SAndreas Gohr     * Open an ordered list
241*93075b01SAndreas Gohr     */
24239a89382SEsther Brunner    function listo_open() {
24339a89382SEsther Brunner        if($this->capture) $this->doc .= DOKU_LF;
24439a89382SEsther Brunner    }
24539a89382SEsther Brunner
246*93075b01SAndreas Gohr    /**
247*93075b01SAndreas Gohr     * Close an ordered list
248*93075b01SAndreas Gohr     */
24939a89382SEsther Brunner    function listo_close() {
25039a89382SEsther Brunner        if($this->capture && (strlen($this->doc) > 250)) $this->capture = false;
25139a89382SEsther Brunner    }
25239a89382SEsther Brunner
253*93075b01SAndreas Gohr    /**
254*93075b01SAndreas Gohr     * Open a list item
255*93075b01SAndreas Gohr     *
256*93075b01SAndreas Gohr     * @param int $level the nesting level
257*93075b01SAndreas Gohr     */
25839a89382SEsther Brunner    function listitem_open($level) {
25939a89382SEsther Brunner        if($this->capture) $this->doc .= str_repeat(DOKU_TAB, $level).'* ';
26039a89382SEsther Brunner    }
26139a89382SEsther Brunner
262*93075b01SAndreas Gohr    /**
263*93075b01SAndreas Gohr     * Close a list item
264*93075b01SAndreas Gohr     */
26539a89382SEsther Brunner    function listitem_close() {
26639a89382SEsther Brunner        if($this->capture) $this->doc .= DOKU_LF;
26739a89382SEsther Brunner    }
26839a89382SEsther Brunner
269*93075b01SAndreas Gohr    /**
270*93075b01SAndreas Gohr     * Output preformatted text
271*93075b01SAndreas Gohr     *
272*93075b01SAndreas Gohr     * @param string $text
273*93075b01SAndreas Gohr     */
27439a89382SEsther Brunner    function preformatted($text) {
27539a89382SEsther Brunner        if($this->capture) $this->doc .= $text;
27639a89382SEsther Brunner    }
27739a89382SEsther Brunner
278*93075b01SAndreas Gohr    /**
279*93075b01SAndreas Gohr     * Start a block quote
280*93075b01SAndreas Gohr     */
28139a89382SEsther Brunner    function quote_open() {
28271b40da2SAnika Henke        if($this->capture) $this->doc .= DOKU_LF.DOKU_TAB.'"';
28339a89382SEsther Brunner    }
28439a89382SEsther Brunner
285*93075b01SAndreas Gohr    /**
286*93075b01SAndreas Gohr     * Stop a block quote
287*93075b01SAndreas Gohr     */
28839a89382SEsther Brunner    function quote_close() {
28939a89382SEsther Brunner        if($this->capture) {
29071b40da2SAnika Henke            $this->doc .= '"';
29139a89382SEsther Brunner            if(strlen($this->doc) > 250) $this->capture = false;
29239a89382SEsther Brunner            else $this->doc .= DOKU_LF;
29339a89382SEsther Brunner        }
29439a89382SEsther Brunner    }
29539a89382SEsther Brunner
296*93075b01SAndreas Gohr    /**
297*93075b01SAndreas Gohr     * Display text as file content, optionally syntax highlighted
298*93075b01SAndreas Gohr     *
299*93075b01SAndreas Gohr     * @param string $text text to show
300*93075b01SAndreas Gohr     * @param string $lang programming language to use for syntax highlighting
301*93075b01SAndreas Gohr     * @param string $file file path label
302*93075b01SAndreas Gohr     */
303*93075b01SAndreas Gohr    function file($text, $lang = null, $file = null) {
304*93075b01SAndreas Gohr        if($this->capture) {
305*93075b01SAndreas Gohr            $this->doc .= DOKU_LF.$text;
306*93075b01SAndreas Gohr            if(strlen($this->doc) > 250) $this->capture = false;
307*93075b01SAndreas Gohr            else $this->doc .= DOKU_LF;
308*93075b01SAndreas Gohr        }
309*93075b01SAndreas Gohr    }
310*93075b01SAndreas Gohr
311*93075b01SAndreas Gohr    /**
312*93075b01SAndreas Gohr     * Display text as code content, optionally syntax highlighted
313*93075b01SAndreas Gohr     *
314*93075b01SAndreas Gohr     * @param string $text     text to show
315*93075b01SAndreas Gohr     * @param string $language programming language to use for syntax highlighting
316*93075b01SAndreas Gohr     * @param string $file     file path label
317*93075b01SAndreas Gohr     */
3180ea51e63SMatt Perry    function code($text, $language = null, $file = null) {
31939a89382SEsther Brunner        if($this->capture) {
32039a89382SEsther Brunner            $this->doc .= DOKU_LF.$text;
32139a89382SEsther Brunner            if(strlen($this->doc) > 250) $this->capture = false;
32239a89382SEsther Brunner            else $this->doc .= DOKU_LF;
32339a89382SEsther Brunner        }
32439a89382SEsther Brunner    }
32539a89382SEsther Brunner
326*93075b01SAndreas Gohr    /**
327*93075b01SAndreas Gohr     * Format an acronym
328*93075b01SAndreas Gohr     *
329*93075b01SAndreas Gohr     * Uses $this->acronyms
330*93075b01SAndreas Gohr     *
331*93075b01SAndreas Gohr     * @param string $acronym
332*93075b01SAndreas Gohr     */
33339a89382SEsther Brunner    function acronym($acronym) {
33439a89382SEsther Brunner        if($this->capture) $this->doc .= $acronym;
33539a89382SEsther Brunner    }
33639a89382SEsther Brunner
337*93075b01SAndreas Gohr    /**
338*93075b01SAndreas Gohr     * Format a smiley
339*93075b01SAndreas Gohr     *
340*93075b01SAndreas Gohr     * Uses $this->smiley
341*93075b01SAndreas Gohr     *
342*93075b01SAndreas Gohr     * @param string $smiley
343*93075b01SAndreas Gohr     */
34439a89382SEsther Brunner    function smiley($smiley) {
34539a89382SEsther Brunner        if($this->capture) $this->doc .= $smiley;
34639a89382SEsther Brunner    }
34739a89382SEsther Brunner
348*93075b01SAndreas Gohr    /**
349*93075b01SAndreas Gohr     * Format an entity
350*93075b01SAndreas Gohr     *
351*93075b01SAndreas Gohr     * Entities are basically small text replacements
352*93075b01SAndreas Gohr     *
353*93075b01SAndreas Gohr     * Uses $this->entities
354*93075b01SAndreas Gohr     *
355*93075b01SAndreas Gohr     * @param string $entity
356*93075b01SAndreas Gohr     */
35739a89382SEsther Brunner    function entity($entity) {
35839a89382SEsther Brunner        if($this->capture) $this->doc .= $entity;
35939a89382SEsther Brunner    }
36039a89382SEsther Brunner
361*93075b01SAndreas Gohr    /**
362*93075b01SAndreas Gohr     * Typographically format a multiply sign
363*93075b01SAndreas Gohr     *
364*93075b01SAndreas Gohr     * Example: ($x=640, $y=480) should result in "640×480"
365*93075b01SAndreas Gohr     *
366*93075b01SAndreas Gohr     * @param string|int $x first value
367*93075b01SAndreas Gohr     * @param string|int $y second value
368*93075b01SAndreas Gohr     */
36939a89382SEsther Brunner    function multiplyentity($x, $y) {
37039a89382SEsther Brunner        if($this->capture) $this->doc .= $x.'×'.$y;
37139a89382SEsther Brunner    }
37239a89382SEsther Brunner
373*93075b01SAndreas Gohr    /**
374*93075b01SAndreas Gohr     * Render an opening single quote char (language specific)
375*93075b01SAndreas Gohr     */
37639a89382SEsther Brunner    function singlequoteopening() {
37771b40da2SAnika Henke        global $lang;
37871b40da2SAnika Henke        if($this->capture) $this->doc .= $lang['singlequoteopening'];
37939a89382SEsther Brunner    }
38039a89382SEsther Brunner
381*93075b01SAndreas Gohr    /**
382*93075b01SAndreas Gohr     * Render a closing single quote char (language specific)
383*93075b01SAndreas Gohr     */
38439a89382SEsther Brunner    function singlequoteclosing() {
38571b40da2SAnika Henke        global $lang;
38671b40da2SAnika Henke        if($this->capture) $this->doc .= $lang['singlequoteclosing'];
38739a89382SEsther Brunner    }
38839a89382SEsther Brunner
389*93075b01SAndreas Gohr    /**
390*93075b01SAndreas Gohr     * Render an apostrophe char (language specific)
391*93075b01SAndreas Gohr     */
39257d757d1SAndreas Gohr    function apostrophe() {
39357d757d1SAndreas Gohr        global $lang;
394b58f5d31STom N Harris        if($this->capture) $this->doc .= $lang['apostrophe'];
39557d757d1SAndreas Gohr    }
39657d757d1SAndreas Gohr
397*93075b01SAndreas Gohr    /**
398*93075b01SAndreas Gohr     * Render an opening double quote char (language specific)
399*93075b01SAndreas Gohr     */
40039a89382SEsther Brunner    function doublequoteopening() {
40171b40da2SAnika Henke        global $lang;
40271b40da2SAnika Henke        if($this->capture) $this->doc .= $lang['doublequoteopening'];
40339a89382SEsther Brunner    }
40439a89382SEsther Brunner
405*93075b01SAndreas Gohr    /**
406*93075b01SAndreas Gohr     * Render an closinging double quote char (language specific)
407*93075b01SAndreas Gohr     */
40839a89382SEsther Brunner    function doublequoteclosing() {
40971b40da2SAnika Henke        global $lang;
41071b40da2SAnika Henke        if($this->capture) $this->doc .= $lang['doublequoteclosing'];
41139a89382SEsther Brunner    }
41239a89382SEsther Brunner
413*93075b01SAndreas Gohr    /**
414*93075b01SAndreas Gohr     * Render a CamelCase link
415*93075b01SAndreas Gohr     *
416*93075b01SAndreas Gohr     * @param string $link The link name
417*93075b01SAndreas Gohr     * @see http://en.wikipedia.org/wiki/CamelCase
418*93075b01SAndreas Gohr     */
41939a89382SEsther Brunner    function camelcaselink($link) {
42039a89382SEsther Brunner        $this->internallink($link, $link);
42139a89382SEsther Brunner    }
42239a89382SEsther Brunner
423*93075b01SAndreas Gohr    /**
424*93075b01SAndreas Gohr     * Render a page local link
425*93075b01SAndreas Gohr     *
426*93075b01SAndreas Gohr     * @param string $hash hash link identifier
427*93075b01SAndreas Gohr     * @param string $name name for the link
428*93075b01SAndreas Gohr     */
4299269d0b1SMichael Hamann    function locallink($hash, $name = null) {
4309269d0b1SMichael Hamann        if(is_array($name)) {
4319269d0b1SMichael Hamann            $this->_firstimage($name['src']);
4329269d0b1SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
4339269d0b1SMichael Hamann        }
4349269d0b1SMichael Hamann    }
43539a89382SEsther Brunner
43639a89382SEsther Brunner    /**
43739a89382SEsther Brunner     * keep track of internal links in $this->meta['relation']['references']
438*93075b01SAndreas Gohr     *
439*93075b01SAndreas Gohr     * @param string       $id   page ID to link to. eg. 'wiki:syntax'
440*93075b01SAndreas Gohr     * @param string|array $name name for the link, array for media file
44139a89382SEsther Brunner     */
4420ea51e63SMatt Perry    function internallink($id, $name = null) {
44339a89382SEsther Brunner        global $ID;
44439a89382SEsther Brunner
445ffec1009SMichael Hamann        if(is_array($name)) {
446aa5a2937SAndreas Gohr            $this->_firstimage($name['src']);
447ffec1009SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
448ffec1009SMichael Hamann        }
449aa5a2937SAndreas Gohr
45066d935e7SMichael Hamann        $parts = explode('?', $id, 2);
45166d935e7SMichael Hamann        if(count($parts) === 2) {
45266d935e7SMichael Hamann            $id = $parts[0];
45366d935e7SMichael Hamann        }
45466d935e7SMichael Hamann
45539a89382SEsther Brunner        $default = $this->_simpleTitle($id);
45639a89382SEsther Brunner
45739a89382SEsther Brunner        // first resolve and clean up the $id
45839a89382SEsther Brunner        resolve_pageid(getNS($ID), $id, $exists);
459*93075b01SAndreas Gohr        @list($page) = explode('#', $id, 2);
46039a89382SEsther Brunner
46139a89382SEsther Brunner        // set metadata
4623be6e394Schris        $this->meta['relation']['references'][$page] = $exists;
46339a89382SEsther Brunner        // $data = array('relation' => array('isreferencedby' => array($ID => true)));
46439a89382SEsther Brunner        // p_set_metadata($id, $data);
46539a89382SEsther Brunner
46639a89382SEsther Brunner        // add link title to summary
46739a89382SEsther Brunner        if($this->capture) {
46839a89382SEsther Brunner            $name = $this->_getLinkTitle($name, $default, $id);
46939a89382SEsther Brunner            $this->doc .= $name;
47039a89382SEsther Brunner        }
47139a89382SEsther Brunner    }
47239a89382SEsther Brunner
473*93075b01SAndreas Gohr    /**
474*93075b01SAndreas Gohr     * Render an external link
475*93075b01SAndreas Gohr     *
476*93075b01SAndreas Gohr     * @param string       $url  full URL with scheme
477*93075b01SAndreas Gohr     * @param string|array $name name for the link, array for media file
478*93075b01SAndreas Gohr     */
4790ea51e63SMatt Perry    function externallink($url, $name = null) {
480ffec1009SMichael Hamann        if(is_array($name)) {
481aa5a2937SAndreas Gohr            $this->_firstimage($name['src']);
482ffec1009SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
483ffec1009SMichael Hamann        }
484aa5a2937SAndreas Gohr
48539a89382SEsther Brunner        if($this->capture) {
486a2ea2dc1SAdrian Lang            $this->doc .= $this->_getLinkTitle($name, '<'.$url.'>');
48739a89382SEsther Brunner        }
48839a89382SEsther Brunner    }
48939a89382SEsther Brunner
490*93075b01SAndreas Gohr    /**
491*93075b01SAndreas Gohr     * Render an interwiki link
492*93075b01SAndreas Gohr     *
493*93075b01SAndreas Gohr     * You may want to use $this->_resolveInterWiki() here
494*93075b01SAndreas Gohr     *
495*93075b01SAndreas Gohr     * @param string       $match     original link - probably not much use
496*93075b01SAndreas Gohr     * @param string|array $name      name for the link, array for media file
497*93075b01SAndreas Gohr     * @param string       $wikiName  indentifier (shortcut) for the remote wiki
498*93075b01SAndreas Gohr     * @param string       $wikiUri   the fragment parsed from the original link
499*93075b01SAndreas Gohr     */
5000ea51e63SMatt Perry    function interwikilink($match, $name = null, $wikiName, $wikiUri) {
501ffec1009SMichael Hamann        if(is_array($name)) {
502aa5a2937SAndreas Gohr            $this->_firstimage($name['src']);
503ffec1009SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
504ffec1009SMichael Hamann        }
505aa5a2937SAndreas Gohr
50639a89382SEsther Brunner        if($this->capture) {
507*93075b01SAndreas Gohr            list($wikiUri) = explode('#', $wikiUri, 2);
508a2ea2dc1SAdrian Lang            $name = $this->_getLinkTitle($name, $wikiUri);
50939a89382SEsther Brunner            $this->doc .= $name;
51039a89382SEsther Brunner        }
51139a89382SEsther Brunner    }
51239a89382SEsther Brunner
513*93075b01SAndreas Gohr    /**
514*93075b01SAndreas Gohr     * Link to windows share
515*93075b01SAndreas Gohr     *
516*93075b01SAndreas Gohr     * @param string       $url  the link
517*93075b01SAndreas Gohr     * @param string|array $name name for the link, array for media file
518*93075b01SAndreas Gohr     */
5190ea51e63SMatt Perry    function windowssharelink($url, $name = null) {
520ffec1009SMichael Hamann        if(is_array($name)) {
521aa5a2937SAndreas Gohr            $this->_firstimage($name['src']);
522ffec1009SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
523ffec1009SMichael Hamann        }
524aa5a2937SAndreas Gohr
52539a89382SEsther Brunner        if($this->capture) {
52639a89382SEsther Brunner            if($name) $this->doc .= $name;
52739a89382SEsther Brunner            else $this->doc .= '<'.$url.'>';
52839a89382SEsther Brunner        }
52939a89382SEsther Brunner    }
53039a89382SEsther Brunner
531*93075b01SAndreas Gohr    /**
532*93075b01SAndreas Gohr     * Render a linked E-Mail Address
533*93075b01SAndreas Gohr     *
534*93075b01SAndreas Gohr     * Should honor $conf['mailguard'] setting
535*93075b01SAndreas Gohr     *
536*93075b01SAndreas Gohr     * @param string       $address Email-Address
537*93075b01SAndreas Gohr     * @param string|array $name    name for the link, array for media file
538*93075b01SAndreas Gohr     */
5390ea51e63SMatt Perry    function emaillink($address, $name = null) {
540ffec1009SMichael Hamann        if(is_array($name)) {
541aa5a2937SAndreas Gohr            $this->_firstimage($name['src']);
542ffec1009SMichael Hamann            if($name['type'] == 'internalmedia') $this->_recordMediaUsage($name['src']);
543ffec1009SMichael Hamann        }
544aa5a2937SAndreas Gohr
54539a89382SEsther Brunner        if($this->capture) {
54639a89382SEsther Brunner            if($name) $this->doc .= $name;
54739a89382SEsther Brunner            else $this->doc .= '<'.$address.'>';
54839a89382SEsther Brunner        }
54939a89382SEsther Brunner    }
55039a89382SEsther Brunner
551*93075b01SAndreas Gohr    /**
552*93075b01SAndreas Gohr     * Render an internal media file
553*93075b01SAndreas Gohr     *
554*93075b01SAndreas Gohr     * @param string $src     media ID
555*93075b01SAndreas Gohr     * @param string $title   descriptive text
556*93075b01SAndreas Gohr     * @param string $align   left|center|right
557*93075b01SAndreas Gohr     * @param int    $width   width of media in pixel
558*93075b01SAndreas Gohr     * @param int    $height  height of media in pixel
559*93075b01SAndreas Gohr     * @param string $cache   cache|recache|nocache
560*93075b01SAndreas Gohr     * @param string $linking linkonly|detail|nolink
561*93075b01SAndreas Gohr     */
5620ea51e63SMatt Perry    function internalmedia($src, $title = null, $align = null, $width = null,
5630ea51e63SMatt Perry                           $height = null, $cache = null, $linking = null) {
56439a89382SEsther Brunner        if($this->capture && $title) $this->doc .= '['.$title.']';
565aa5a2937SAndreas Gohr        $this->_firstimage($src);
566ffec1009SMichael Hamann        $this->_recordMediaUsage($src);
56739a89382SEsther Brunner    }
56839a89382SEsther Brunner
569*93075b01SAndreas Gohr    /**
570*93075b01SAndreas Gohr     * Render an external media file
571*93075b01SAndreas Gohr     *
572*93075b01SAndreas Gohr     * @param string $src     full media URL
573*93075b01SAndreas Gohr     * @param string $title   descriptive text
574*93075b01SAndreas Gohr     * @param string $align   left|center|right
575*93075b01SAndreas Gohr     * @param int    $width   width of media in pixel
576*93075b01SAndreas Gohr     * @param int    $height  height of media in pixel
577*93075b01SAndreas Gohr     * @param string $cache   cache|recache|nocache
578*93075b01SAndreas Gohr     * @param string $linking linkonly|detail|nolink
579*93075b01SAndreas Gohr     */
5800ea51e63SMatt Perry    function externalmedia($src, $title = null, $align = null, $width = null,
5810ea51e63SMatt Perry                           $height = null, $cache = null, $linking = null) {
58239a89382SEsther Brunner        if($this->capture && $title) $this->doc .= '['.$title.']';
583aa5a2937SAndreas Gohr        $this->_firstimage($src);
58439a89382SEsther Brunner    }
58539a89382SEsther Brunner
586*93075b01SAndreas Gohr    /**
587*93075b01SAndreas Gohr     * Render the output of an RSS feed
588*93075b01SAndreas Gohr     *
589*93075b01SAndreas Gohr     * @param string $url    URL of the feed
590*93075b01SAndreas Gohr     * @param array  $params Finetuning of the output
591*93075b01SAndreas Gohr     */
592ce6b63d9Schris    function rss($url, $params) {
593ce6b63d9Schris        $this->meta['relation']['haspart'][$url] = true;
59464e9144aSchris
59564e9144aSchris        $this->meta['date']['valid']['age'] =
59664e9144aSchris            isset($this->meta['date']['valid']['age']) ?
59764e9144aSchris                min($this->meta['date']['valid']['age'], $params['refresh']) :
59864e9144aSchris                $params['refresh'];
599ce6b63d9Schris    }
60039a89382SEsther Brunner
601*93075b01SAndreas Gohr    #region Utils
60239a89382SEsther Brunner
60339a89382SEsther Brunner    /**
60439a89382SEsther Brunner     * Removes any Namespace from the given name but keeps
60539a89382SEsther Brunner     * casing and special chars
60639a89382SEsther Brunner     *
60739a89382SEsther Brunner     * @author Andreas Gohr <andi@splitbrain.org>
60839a89382SEsther Brunner     */
60939a89382SEsther Brunner    function _simpleTitle($name) {
61039a89382SEsther Brunner        global $conf;
61139a89382SEsther Brunner
6129bee852eSAndreas Gohr        if(is_array($name)) return '';
6139bee852eSAndreas Gohr
61439a89382SEsther Brunner        if($conf['useslash']) {
61539a89382SEsther Brunner            $nssep = '[:;/]';
61639a89382SEsther Brunner        } else {
61739a89382SEsther Brunner            $nssep = '[:;]';
61839a89382SEsther Brunner        }
61939a89382SEsther Brunner        $name = preg_replace('!.*'.$nssep.'!', '', $name);
6203be6e394Schris        //if there is a hash we use the anchor name only
62139a89382SEsther Brunner        $name = preg_replace('!.*#!', '', $name);
62239a89382SEsther Brunner        return $name;
62339a89382SEsther Brunner    }
62439a89382SEsther Brunner
62539a89382SEsther Brunner    /**
62639a89382SEsther Brunner     * Creates a linkid from a headline
62739a89382SEsther Brunner     *
628*93075b01SAndreas Gohr     * @author Andreas Gohr <andi@splitbrain.org>
62939a89382SEsther Brunner     * @param string  $title   The headline title
63039a89382SEsther Brunner     * @param boolean $create  Create a new unique ID?
631*93075b01SAndreas Gohr     * @return string
63239a89382SEsther Brunner     */
63339a89382SEsther Brunner    function _headerToLink($title, $create = false) {
63439a89382SEsther Brunner        if($create) {
635620f4930SAndreas Gohr            return sectionID($title, $this->headers);
636620f4930SAndreas Gohr        } else {
637620f4930SAndreas Gohr            $check = false;
638620f4930SAndreas Gohr            return sectionID($title, $check);
63939a89382SEsther Brunner        }
64039a89382SEsther Brunner    }
64139a89382SEsther Brunner
64239a89382SEsther Brunner    /**
64339a89382SEsther Brunner     * Construct a title and handle images in titles
64439a89382SEsther Brunner     *
64539a89382SEsther Brunner     * @author Harry Fuecks <hfuecks@gmail.com>
646*93075b01SAndreas Gohr     * @param string|array $title    either string title or media array
647*93075b01SAndreas Gohr     * @param string       $default  default title if nothing else is found
648*93075b01SAndreas Gohr     * @param null|string  $id       linked page id (used to extract title from first heading)
649*93075b01SAndreas Gohr     * @return string title text
65039a89382SEsther Brunner     */
6510ea51e63SMatt Perry    function _getLinkTitle($title, $default, $id = null) {
65285038eabSDanny        if(is_array($title)) {
653*93075b01SAndreas Gohr            if($title['title']) {
654*93075b01SAndreas Gohr                return '['.$title['title'].']';
655*93075b01SAndreas Gohr            } else {
656*93075b01SAndreas Gohr                return $default;
657*93075b01SAndreas Gohr            }
65885038eabSDanny        } else if(is_null($title) || trim($title) == '') {
659fe9ec250SChris Smith            if(useHeading('content') && $id) {
66020f04039SDanny                $heading = p_get_first_heading($id, METADATA_DONT_RENDER);
66139a89382SEsther Brunner                if($heading) return $heading;
66239a89382SEsther Brunner            }
66339a89382SEsther Brunner            return $default;
66485038eabSDanny        } else {
66539a89382SEsther Brunner            return $title;
66639a89382SEsther Brunner        }
66739a89382SEsther Brunner    }
66839a89382SEsther Brunner
669*93075b01SAndreas Gohr    /**
670*93075b01SAndreas Gohr     * Remember first image
671*93075b01SAndreas Gohr     *
672*93075b01SAndreas Gohr     * @param string $src image URL or ID
673*93075b01SAndreas Gohr     */
674aa5a2937SAndreas Gohr    function _firstimage($src) {
675aa5a2937SAndreas Gohr        if($this->firstimage) return;
676aa5a2937SAndreas Gohr        global $ID;
677aa5a2937SAndreas Gohr
678*93075b01SAndreas Gohr        list($src) = explode('#', $src, 2);
6793e7e6067SKlap-in        if(!media_isexternal($src)) {
680aa5a2937SAndreas Gohr            resolve_mediaid(getNS($ID), $src, $exists);
681aa5a2937SAndreas Gohr        }
682aa5a2937SAndreas Gohr        if(preg_match('/.(jpe?g|gif|png)$/i', $src)) {
683aa5a2937SAndreas Gohr            $this->firstimage = $src;
684aa5a2937SAndreas Gohr        }
685aa5a2937SAndreas Gohr    }
686ffec1009SMichael Hamann
687*93075b01SAndreas Gohr    /**
688*93075b01SAndreas Gohr     * Store list of used media files in metadata
689*93075b01SAndreas Gohr     *
690*93075b01SAndreas Gohr     * @param string $src media ID
691*93075b01SAndreas Gohr     */
692ffec1009SMichael Hamann    function _recordMediaUsage($src) {
693ffec1009SMichael Hamann        global $ID;
694ffec1009SMichael Hamann
695*93075b01SAndreas Gohr        list ($src) = explode('#', $src, 2);
696ffec1009SMichael Hamann        if(media_isexternal($src)) return;
697ffec1009SMichael Hamann        resolve_mediaid(getNS($ID), $src, $exists);
698ffec1009SMichael Hamann        $this->meta['relation']['media'][$src] = $exists;
699ffec1009SMichael Hamann    }
700*93075b01SAndreas Gohr
701*93075b01SAndreas Gohr    #endregion
70239a89382SEsther Brunner}
70339a89382SEsther Brunner
704e3776c06SMichael Hamann//Setup VIM: ex: et ts=4 :
705