source: applications/nimpad/trunk/lib/HatenaSyntax/TOCRenderer.php @ 1490

SVN
Revision 1490, 3.0 KB checked in by anatoo, 10 months ago (diff)

0.2ブランチのリビジョン1489,1488の変更をtrunkに取り込んだ

Line 
1<?php
2/**
3 * @package HatenaSyntax
4 * @author anatoo<anatoo@nequal.jp>
5 * @license http://www.opensource.org/licenses/mit-license.php MIT License
6 * @version $Id: TOCRenderer.php 1163 2009-09-07 17:16:34Z anatoo $
7 */
8
9class HatenaSyntax_TOCRenderer
10{
11    protected $headerCount;
12   
13    function render(HatenaSyntax_Node $rootnode, $id)
14    {
15        $treeroot = HatenaSyntax_Tree::make($this->filter($rootnode));
16        $this->headerCount = 0;
17        $this->id = $id;
18        $renderer = new HatenaSyntax_TreeRenderer(array($this, 'renderHeader'));
19        return '<div class="toc">' . $renderer->render($treeroot) . '</div>';
20    }
21   
22    protected function escape($str)
23    {
24        return htmlspecialchars($str, ENT_QUOTES);
25    }
26   
27    function renderHeader($node)
28    {
29        $count = $this->headerCount++;
30        $buf = array();
31        $data = $node->getData();
32        foreach ($data['body'] as $leaf) {
33            if (is_string($leaf)) {
34                $buf[] = $leaf;
35            }
36            else {
37                $buf [] = $this->{'render' . $leaf->getType()}($lead->getData());
38            }
39        }
40        return '<a href="#' . $this->id . '_header_' . $count . '">' . $this->escape(join('', $buf)) . '</a>';
41    }
42   
43    protected function renderFootnote($data)
44    {
45        return '';
46    }
47   
48    function filter(HatenaSyntax_Node $rootnode)
49    {
50        if ($rootnode->getType() !== 'root') throw new Exception;
51        $header_arr = $this->fetchHeader($rootnode);
52        $ret = array();
53        foreach ($header_arr as $header) {
54            $buf = $header->getData();
55            $ret[] = array('level' => $buf['level'], 'value' => $header);
56        }
57        return $ret;
58    }
59   
60    protected function fetchHeader($node)
61    {
62        return $this->{'fetchHeaderIn' . $node->getType()}($node);
63    }
64   
65    protected function fetchHeaderInRoot($node)
66    {
67        $buf = array();
68        foreach ($node->getData() as $node) {
69            $buf[] = $this->fetchHeader($node);
70        }
71       
72        return $this->concat($buf);
73    }
74   
75    protected function fetchHeaderInHeader($node)
76    {
77        return array($node);
78    }
79   
80    protected function fetchHeaderInBlockQuote($node)
81    {
82        $buf = array();
83        $data = $node->getData();
84        foreach ($data['body'] as $node) {
85            $buf[] = $this->fetchHeader($node);
86        }
87        return $this->concat($buf);
88    }
89
90    function __call($name, $args)
91    {
92        if (preg_match('#^fetchHeaderIn\w+$#i', $name)) return array();
93        throw new Exception(sprintf('method(%s) not found', $name));
94    }
95   
96    protected function concat(Array $target)
97    {
98        if (!$target) return array();
99        $target = array_reverse($target);
100        while (1 < count($target)) {
101            array_push($target, array_merge(array_pop($target), array_pop($target)));
102        }
103        return $target[0];
104    }
105}
Note: See TracBrowser for help on using the repository browser.